关于#java#的问题:使用easyPoi导出word模板时出现问题

使用easyPoi导出word模板时出现问题

img


img


img


这三张图片分别是 代码 想要的结果图片 word模板
求指点!

出啥问题你没说吖

可以参考这个改下

看了下源码,表格循环生成仅支持单行的,所以估计不支持你想要的这种跨行生成的效果。考虑换框架或者自己继承源码写实现吧。
自己写实现的话,可以考虑优化我写的这个,修改修改应该就可以了。

package service;

import cn.afterturn.easypoi.cache.WordCache;
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.util.PoiPublicUtil;
import cn.afterturn.easypoi.word.entity.MyXWPFDocument;
import cn.afterturn.easypoi.word.entity.params.ExcelListEntity;
import cn.afterturn.easypoi.word.parse.ParseWord07;
import cn.afterturn.easypoi.word.parse.excel.ExcelEntityParse;
import cn.afterturn.easypoi.word.parse.excel.ExcelMapParse;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static cn.afterturn.easypoi.util.PoiElUtil.*;
import static cn.afterturn.easypoi.util.PoiElUtil.EMPTY;

public class ParseWord07Enhance extends ParseWord07 {
    /**
     * 解析07版的Word并且进行赋值
     *
     * @return
     * @throws Exception
     * @author JueYue
     * 2013-11-16
     */
    public XWPFDocument parseWord(String url, Map<String, Object> map) throws Exception {
        MyXWPFDocument doc = WordCache.getXWPFDocumen(url);
        parseWordSetValue(doc, map);
        return doc;
    }
    /**
     * 解析页眉和页脚
     *
     * @param doc
     * @param map
     * @throws Exception
     */
    private void parseHeaderAndFoot(MyXWPFDocument doc, Map<String, Object> map) throws Exception {
        List<XWPFHeader> headerList = doc.getHeaderList();
        for (XWPFHeader xwpfHeader : headerList) {
            for (int i = 0; i < xwpfHeader.getListParagraph().size(); i++) {
                parseThisParagraph(xwpfHeader.getListParagraph().get(i), map);
            }
        }
        List<XWPFFooter> footerList = doc.getFooterList();
        for (XWPFFooter xwpfFooter : footerList) {
            for (int i = 0; i < xwpfFooter.getListParagraph().size(); i++) {
                parseThisParagraph(xwpfFooter.getListParagraph().get(i), map);
            }
        }

    }

    private void parseWordSetValue(MyXWPFDocument doc, Map<String, Object> map) throws Exception {
        // 第一步解析文档
        parseAllParagraphic(doc.getParagraphs(), map);
        // 第二步解析页眉,页脚
        parseHeaderAndFoot(doc, map);
        // 第三步解析所有表格
        XWPFTable           table;
        Iterator<XWPFTable> itTable = doc.getTablesIterator();
        while (itTable.hasNext()) {
            table = itTable.next();
            if (table.getText().indexOf(START_STR) != -1) {
                parseThisTable(table, map);
            }
        }

    }
    private void parseThisTable(XWPFTable table, Map<String, Object> map) throws Exception {
        XWPFTableRow row;
        List<XWPFTableCell> cells;
        Object              listobj;
        for (int i = 0; i < table.getNumberOfRows(); i++) {
            row = table.getRow(i);
            cells = row.getTableCells();
            listobj = checkThisTableIsNeedIterator(cells.get(0), map);
            if (listobj == null) {
                parseThisRow(cells, map);
            } else if (listobj instanceof ExcelListEntity) {
                new ExcelEntityParse().parseNextRowAndAddRow(table, i, (ExcelListEntity) listobj);
                i = i + ((ExcelListEntity) listobj).getList().size() - 1;//删除之后要往上挪一行,然后加上跳过新建的行数
            } else {
                if (isStartRow(cells)){
                    int endIndex=getEndRowIndex(table,i,table.getNumberOfRows());
                    int space=endIndex-i+1;
                    if (endIndex>0){
                        List listobj1 = (List) listobj;
                        for (int k = 0,len=listobj1.size(); k < len; k++) {
                            Object o=listobj1.get(k);
                            ArrayList<Object> temp = new ArrayList<>();
                            temp.add(o);
                            for (int j=i; j <= endIndex; j++) {
                                ExcelMapParseFace.parseNextRowAndAddRow(table, j,space, temp,k==len-1);
                            }
                        }
                        for (int j=i; j <= endIndex; j++) {
                            table.removeRow(j);
                        }
                    }
                }else {
                    ExcelMapParse.parseNextRowAndAddRow(table, i, (List) listobj);
                    i = i + ((List) listobj).size() - 1;//删除之后要往上挪一行,然后加上跳过新建的行数
                }
            }
        }
    }

    private int getEndRowIndex(XWPFTable table,int curIndex, int numberOfRows) {
        XWPFTableRow row;
        List<XWPFTableCell> cells;
        Object              listobj;
        for (int i = curIndex; i < table.getNumberOfRows(); i++) {
            row = table.getRow(i);
            cells = row.getTableCells();
            if (isEndRow(cells)){
                return i;
            }
        }
        return -1;
    }

    /**
     * table起始行
     * @param cells
     * @return
     */
    private boolean isEndRow(List<XWPFTableCell> cells) {
        for (XWPFTableCell cell : cells) {
            String text = cell.getText().trim();
            if (text.contains(END_STR)){
                return true;
            }
        }
        return false;
    }


    /**
     * table起始行
     * @param cells
     * @return
     */
    private boolean isStartRow(List<XWPFTableCell> cells) {
        for (XWPFTableCell cell : cells) {
            String text = cell.getText().trim();
            if (text.contains(END_STR)){
                return false;
            }
        }
        return true;
    }

    /**
     * 解析这个段落
     *
     * @param paragraph
     * @param map
     * @author JueYue
     * 2013-11-16
     */
    private void parseThisParagraph(XWPFParagraph paragraph,
                                    Map<String, Object> map) throws Exception {
        XWPFRun run;
        XWPFRun       currentRun  = null;// 拿到的第一个run,用来set值,可以保存格式
        String        currentText = "";// 存放当前的text
        String        text;
        Boolean       isfinde     = false;// 判断是不是已经遇到{{
        List<Integer> runIndex    = new ArrayList<Integer>();// 存储遇到的run,把他们置空
        for (int i = 0; i < paragraph.getRuns().size(); i++) {
            run = paragraph.getRuns().get(i);
            text = run.getText(0);
            if (StringUtils.isEmpty(text)) {
                continue;
            } // 如果为空或者""这种这继续循环跳过
            if (isfinde) {
                currentText += text;
                if (currentText.indexOf(START_STR) == -1) {
                    isfinde = false;
                    runIndex.clear();
                } else {
                    runIndex.add(i);
                }
                if (currentText.indexOf(END_STR) != -1) {
                    changeValues(paragraph, currentRun, currentText, runIndex, map);
                    currentText = "";
                    isfinde = false;
                }
            } else if (text.indexOf(START_STR) >= 0) {// 判断是不是开始
                currentText = text;
                isfinde = true;
                currentRun = run;
            } else {
                currentText = "";
            }
            if (currentText.indexOf(END_STR) != -1) {
                changeValues(paragraph, currentRun, currentText, runIndex, map);
                isfinde = false;
            }
        }

    }

    /**
     * 根据条件改变值
     *
     * @param map
     * @author JueYue
     * 2013-11-16
     */
    private void changeValues(XWPFParagraph paragraph, XWPFRun currentRun, String currentText,
                              List<Integer> runIndex, Map<String, Object> map) throws Exception {
        Object obj = PoiPublicUtil.getRealValue(currentText, map);
        if (obj instanceof ImageEntity) {// 如果是图片就设置为图片
            currentRun.setText("", 0);
            ExcelMapParseFace.addAnImage((ImageEntity) obj, currentRun);
        } else {
            currentText = obj.toString();
            PoiPublicUtil.setWordText(currentRun, currentText);
        }
        for (int k = 0; k < runIndex.size(); k++) {
            paragraph.getRuns().get(runIndex.get(k)).setText("", 0);
        }
        runIndex.clear();
    }

    /**
     * 解析所有的文本
     *
     * @param paragraphs
     * @param map
     * @author JueYue
     * 2013-11-17
     */
    private void parseAllParagraphic(List<XWPFParagraph> paragraphs,
                                     Map<String, Object> map) throws Exception {
        XWPFParagraph paragraph;
        for (int i = 0; i < paragraphs.size(); i++) {
            paragraph = paragraphs.get(i);
            if (paragraph.getText().indexOf(START_STR) != -1) {
                parseThisParagraph(paragraph, map);
            }

        }

    }
    private void parseThisRow(List<XWPFTableCell> cells, Map<String, Object> map) throws Exception {
        for (XWPFTableCell cell : cells) {
            parseAllParagraphic(cell.getParagraphs(), map);
        }
    }

    /**
     * 判断是不是迭代输出
     *
     * @return
     * @throws Exception
     * @author JueYue
     * 2013-11-18
     */
    private Object checkThisTableIsNeedIterator(XWPFTableCell cell,
                                                Map<String, Object> map) throws Exception {
        String text = cell.getText().trim();
        // 判断是不是迭代输出
        if (text != null && text.contains(FOREACH) && text.startsWith(START_STR)) {
            text = text.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY)
                    .replace(FOREACH, EMPTY).replace(START_STR, EMPTY);
            String[] keys = text.replaceAll("\\s{1,}", " ").trim().split(" ");
            return PoiPublicUtil.getParamsValue(keys[0], map);
        }
        return null;
    }
}

package service;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.util.PoiPublicUtil;
import cn.afterturn.easypoi.util.PoiWordStyleUtil;
import cn.afterturn.easypoi.word.entity.MyXWPFDocument;
import cn.afterturn.easypoi.word.parse.excel.ExcelMapParse;
import com.google.common.collect.Maps;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static cn.afterturn.easypoi.util.PoiElUtil.*;
import static cn.afterturn.easypoi.util.PoiElUtil.eval;

public class ExcelMapParseFace {
public static void addAnImage(ImageEntity obj, XWPFRun currentRun) {
ExcelMapParse.addAnImage(obj,currentRun);

}
/**
 * 解析参数行,获取参数列表
 *
 * @author JueYue
 *  2013-11-18
 * @param currentRow
 * @return
 */
private static String[] parseCurrentRowGetParams(XWPFTableRow currentRow) {
    List<XWPFTableCell> cells = currentRow.getTableCells();
    String[] params = new String[cells.size()];
    String text;
    for (int i = 0; i < cells.size(); i++) {
        text = cells.get(i).getText();
        params[i] = text == null ? ""
                : text.trim().replace(START_STR, EMPTY).replace(END_STR, EMPTY);
    }
    return params;
}

/**
 * 解析下一行,并且生成更多的行
 * @param table
 * @param index
 * @param list
 */
public static void parseNextRowAndAddRow(XWPFTable table, int index,int space,
                                         List<Object> list,boolean end) throws Exception {
    XWPFTableRow currentRow = table.getRow(index);
    String[] params = parseCurrentRowGetParams(currentRow);
    String listname = params[0];
    boolean isCreate = !listname.contains(FOREACH_NOT_CREATE);
    listname = listname.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY)
            .replace(FOREACH, EMPTY).replace(START_STR, EMPTY);
    String[] keys = listname.replaceAll("\\s{1,}", " ").trim().split(" ");
    if (keys.length>1){
        params[0] = keys[1];
    }else {
        params[0] = keys[0];
    }
    //保存这一行的样式是-后面好统一设置
    List<XWPFTableCell> tempCellList = new ArrayList<XWPFTableCell>();
    tempCellList.addAll(table.getRow(index).getTableCells());
    int cellIndex = 0;
    Map<String, Object> tempMap = Maps.newHashMap();
    for (Object obj : list) {
        currentRow = isCreate ? table.insertNewTableRow(index+space) : table.getRow(index+space);
        tempMap.put("t", obj);
        for (cellIndex = 0; cellIndex < currentRow.getTableCells().size(); cellIndex++) {
            String val = eval(params[cellIndex], tempMap).toString();
            currentRow.getTableCells().get(cellIndex).setText("");
            PoiWordStyleUtil.copyCellAndSetValue(tempCellList.get(cellIndex),
                    currentRow.getTableCells().get(cellIndex), val);
        }

        for (; cellIndex < params.length; cellIndex++) {
            String val = eval(params[cellIndex], tempMap).toString();
            PoiWordStyleUtil.copyCellAndSetValue(tempCellList.get(cellIndex),
                    currentRow.createCell(), val);
        }
    }
}

}


https://wenku.baidu.com/view/68fdc9fecd2f0066f5335a8102d276a201296074.html?_wkts_=1669106703072&bdQuery=java%23%E7%9A%84%E9%97%AE%E9%A2%98%3A%E4%BD%BF%E7%94%A8easyPoi%E5%AF%BC%E5%87%BAword%E6%A8%A1%E6%9D%BF%E6%97%B6%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98

参考一下

java使用easypoi按模板导出word文档遇到的问题_zpzigui的博客-CSDN博客_wordexportutil.exportword07 1.导出时报空指针在项目运行至WordExportUtil.exportWord07(doc, params)方法时报错,首先断点检查doc路径和params内容。检查模板中的{{}}和是否有不必要空格我在模板中的一个表格里粘贴了其他表格的数据,可能造成了有换行,空格的情况。数据全部对照params检查后没问题,将模板中数据项检查,整理表格格式保证全部一致,导出成功。2.使用Jfr... https://blog.csdn.net/yzp950311/article/details/105990499/?ops_request_misc=&request_id=&biz_id=102&utm_term=%E4%BD%BF%E7%94%A8easyPoi%E5%AF%BC%E5%87%BAword%E6%A8%A1%E6%9D%BF%E6%97%B6%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduweb~default-0-105990499.nonecase&spm=1018.2226.3001.4450

那就参考一下呗