参考
https://blog.csdn.net/cheng137666/article/details/111279476
源码测试
输出后
数据无法循环
如何修改源码看自己怎么方便怎么来
比如1.下载源码自己打包再引入; 2.放到自己的私有服; 3.替换(最简单)。
第一列非循环语句时导出为空解决方法
修改2个文件
debug查看到ParseWord07类中的parseThisTable方法,源码如下:
需要改的地方就是第五行,之后替换表格内容的代码最重要的就是listobj参数。这源代码中第五行很明显,他只是根据第一列的内容来获取listobj,而我们的模板循环语句并未在第一列上,因此导致word导出时,无法替换内容。原因讲完了,下面都是动手节了。
替换源码文件,在最上面找到包,这边需要替换2个文件
在本地新建包,然后复制这2个文件到各自的包里面
如下:
然后再修改需要更改的代码
ParseWord07类中 第 199行 方法 替换为下面的
/**
* 解析这个表格
*
* @param table
* @param map
* @author JueYue
* 2013-11-17
*/
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 = null;
int col = 0;
for (XWPFTableCell cell : cells) {
listobj = this.checkThisTableIsNeedIterator(cell, map);
if (listobj != null) {
break;
}
col++;
}
if (listobj == null) {
this.parseThisRow(cells, map);
} else if (listobj instanceof ExcelListEntity) {
(new ExcelEntityParse()).parseNextRowAndAddRow(table, i, (ExcelListEntity) listobj);
i = i + ((ExcelListEntity) listobj).getList().size() - 1;
} else {
ExcelMapParse.parseNextRowAndAddRow(table, i, (List) listobj, col);
i = i + ((List) listobj).size() - 1;
}
}
}
ExcelMapParse 类中 第144 方法替换为下面的
/**
* 解析下一行,并且生成更多的行
*
* @param table
* @param index
* @param list
*/
public static void parseNextRowAndAddRow(XWPFTable table, int index, List<Object> list, int col) throws Exception {
XWPFTableRow currentRow = table.getRow(index);
String[] params = parseCurrentRowGetParams(currentRow);
String listname = params[col];
boolean isCreate = !listname.contains("!fe:");
listname = listname.replace("!fe:", "").replace("$fe:", "").replace("fe:", "").replace("{{", "");
String[] keys = listname.replaceAll("\\s{1,}", " ").trim().split(" ");
params[col] = keys[1];
List<XWPFTableCell> tempCellList = new ArrayList();
tempCellList.addAll(table.getRow(index).getTableCells());
// int cellIndex = false;
Map<String, Object> tempMap = Maps.newHashMap();
LOGGER.debug("start for each data list :{}", list.size());
Iterator var11 = list.iterator();
while (var11.hasNext()) {
Object obj = var11.next();
currentRow = isCreate ? table.insertNewTableRow(index++) : table.getRow(index++);
tempMap.put("t", obj);
//如果有合并单元格情况,会导致params越界,这里需要补齐
String[] paramsNew = (String[]) ArrayUtils.clone(params);
if (params.length < currentRow.getTableCells().size()) {
for (int i = 0; i < currentRow.getTableCells().size() - params.length; i++) {
paramsNew = (String[]) ArrayUtils.add(paramsNew, 0, "placeholderLc_" + i);
}
}
String val;
int cellIndex;
for (cellIndex = 0; cellIndex < currentRow.getTableCells().size(); ++cellIndex) {
val = PoiElUtil.eval(paramsNew[cellIndex], tempMap).toString();
//源代码的bug 此方法无法删除单元格中的内容
//currentRow.getTableCells().get(cellIndex).setText("");
//使用此方法清空单元格内容
if (!Strings.isNullOrEmpty(val)) {
currentRow.getTableCells().get(cellIndex).getParagraphs().forEach(p -> p.getRuns().forEach(r -> r.setText("", 0)));
}
PoiWordStyleUtil.copyCellAndSetValue(cellIndex >= tempCellList.size() ? tempCellList.get(tempCellList.size() - 1) : tempCellList.get(cellIndex)
, currentRow.getTableCells().get(cellIndex), val);
}
while (cellIndex < paramsNew.length) {
val = PoiElUtil.eval(paramsNew[cellIndex], tempMap).toString();
PoiWordStyleUtil.copyCellAndSetValue((XWPFTableCell) tempCellList.get(cellIndex), currentRow.createCell(), val);
++cellIndex;
}
}
table.removeRow(index);
}
重启项目,再次测试
结果
大功告成