package com.gk.hotwork.Domain.Utils; import com.google.common.collect.ImmutableMap; import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; import org.apache.xmlbeans.XmlException; import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject; import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.RenderedImage; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; import java.util.List; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; public class WordTemplate { private XWPFDocument document; private static final String replace_flag_left = "#{"; private static final String replace_flag_right = "}#"; public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分"); public static final SimpleDateFormat sdf_dhms = new SimpleDateFormat("dd日HH时mm分"); //模板里的table public static class Table{ //字段 public String[] fields; //数据 public List data; //<数据,索引> public HashMap index; public Table(String[] fields, List data) { this.fields = fields; this.data = data; this.index = new HashMap<>(); for (int i = 0; i < fields.length; i++) { this.index.put(fields[i], i); } } } public static class Attribute{ public String attribute; public String value; public Attribute(String attribute, String value) { this.attribute = attribute; this.value = value; } } public static class FontCustomize { public int fontSize; public String fontFamily; public FontCustomize(int fontSize, String fontFamily) { this.fontSize = fontSize; this.fontFamily = fontFamily; } } public static class MergeTable extends Table{ public String[] mergeFields; public MergeTable(String[] fields, List data) { super(fields, data); } public MergeTable(String[] fields, String[] mergeFields, List data) { super(fields, data); this.mergeFields = mergeFields; } } //加载,file的加载何,流的加载 二选1 public void loadTemplate(File file,InputStream in) throws IOException{ InputStream target = null; if (file != null) { target = new FileInputStream(file); }else{ target = in; } try{ document = new XWPFDocument(target); target.close(); } catch(IOException ex){ target.close(); throw ex; } } public void saveFile(String fileName) throws IOException { File f=new File(fileName); String a=""; if(!f.exists()){//判断outputFile文件夹下是否存在name文件,不存在,创建 f.createNewFile(); } FileOutputStream fos = new FileOutputStream(f); try{ document.write(fos); fos.close(); }catch (IOException ex){ fos.close(); throw ex; } } public void replaceDocument(Map tableMap,Map paraMap) { List bodyElements = document.getBodyElements(); int templateBodySize = bodyElements.size(); int curT = 0; int curP = 0; for (int a = 0; a < templateBodySize; a++) { IBodyElement body = bodyElements.get(a); // System.out.println( body.getElementType()); if (BodyElementType.TABLE.equals(body.getElementType())) { // XWPFTable table = body.getBody().getTableArray(curT); List tables = body.getBody().getTables(); table = tables.get(curT); if (table != null) { List tableCells = table.getRows().get(0).getTableCells(); // 获取到模板表格第一行,用来判断表格类型 String tableText = table.getText(); if (tableText.indexOf("##{foreach") > -1) { if (tableCells.size() != 2 || tableCells.get(0).getText().indexOf("##{foreach") < 0 || tableCells.get(0).getText().trim().length() == 0) { throw new RuntimeException("need two cell in row."); } String tableType = tableCells.get(0).getText(); String dataSource = tableCells.get(1).getText(); if (!tableMap.containsKey(dataSource)) { throw new RuntimeException("need table:" + dataSource); } Table tableData = tableMap.get(dataSource); if ("##{foreachTable}##".equals(tableType)) { // System.out.println("循环生成表格"); addTableInDocFooterByTable(table, tableData); } else if ("##{foreachTableRow}##".equals(tableType)) { // System.out.println("循环生成表格内部的行"); addTableInDocFooterByRow(table, tableData, paraMap); } } else if (tableText.indexOf("{") > -1) { addTableInDocFooterByParas(table, paraMap); } else { // 没有查找到任何标签,该表格是一个静态表格,仅需要复制一个即可。 addTableInDocFooterByOrigin(table); } curT++; } } else if (BodyElementType.PARAGRAPH.equals(body.getElementType())) {// 处理段落 XWPFParagraph ph = body.getBody().getParagraphArray(curP); if (ph != null) { // htmlText = htmlText+readParagraphX(ph); addParagraphInDocFooter(ph, null, paraMap); curP++; } } else if (BodyElementType.CONTENTCONTROL.equals(body.getElementType())) { IBodyElement bodyElement = bodyElements.get(curP); IBody body1 = bodyElement.getBody(); } } for (int a = 0; a < templateBodySize; a++) { document.removeBodyElement(0); } } // public void replaceDocument2(Map cellMap,Map params) throws IOException, XmlException { List bodyElements = document.getBodyElements(); int templateBodySize = bodyElements.size(); int curT = 0; for (int a = 0; a < templateBodySize; a++) { IBodyElement body = bodyElements.get(a); // System.out.println( body.getElementType()); if (BodyElementType.TABLE.equals(body.getElementType())) { // XWPFTable table = body.getBody().getTableArray(curT); List tables = body.getBody().getTables(); POIXMLDocumentPart part = body.getBody().getPart(); table = tables.get(curT); Table mainTable = cellMap.get("mainTable"); List data = mainTable.data; int remove = 0; List rows = table.getRows(); for (int i = 0; i < rows.size(); i++) { XWPFTableRow row = rows.get(i); List tableCells = row.getTableCells(); for (int j = 0; j < tableCells.size(); j++) { XWPFTableCell cell = tableCells.get(j); String text = cell.getText(); if (params.get(text) != null) { cell.removeParagraph(0); cell.setText(params.get(text)); } //生成表内容 if ("##foreachRows##".equals(cell.getText())) { //从下面一行开始循环生成单元格 XWPFTableRow infoRow = rows.get(i + 1); for (int k = 0; k < mainTable.data.size(); k++) { CTRow ctrow = CTRow.Factory.parse(infoRow.getCtRow().newInputStream()); XWPFTableRow newRow = new XWPFTableRow(ctrow, table); String[] strings = data.get(k); for (int m = 0; m < strings.length; m++) { XWPFTableCell cellSS = newRow.getTableCells().get(m);// 在新增的行上面创建cell //cell.setText(fields.get(k));//不能使用该方法直接加内容,这样会在原内容后面追加,并且不能保证跟原字体样式一致 for (XWPFParagraph p : cellSS.getParagraphs()) { for (XWPFRun r : p.getRuns()) { r.setText(strings[m], 0);//要深入到原cell中的run替换内容才能保证样式一致 } } } table.addRow(newRow, i + k); } //删除####foreachRows##这一行 table.removeRow(i + mainTable.data.size()); //删除type specification num 这一行 table.removeRow(i + mainTable.data.size()); } } } } } } private void addTableInDocFooterByTable(XWPFTable templateTable, Table data) { for (String[] row: data.data) { List templateTableRows = templateTable.getRows();// 获取模板表格所有行 XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列 for (int i = 1; i < templateTableRows.size(); i++) { XWPFTableRow newCreateRow = newCreateTable.createRow(); CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行 } newCreateTable.removeRow(0);// 移除多出来的第一行 document.createParagraph();// 添加回车换行 replaceTable(newCreateTable, getMap(data.index,row));//替换标签 } } private HashMap getMap(HashMap key,String[] row){ HashMap r = new HashMap(); Iterator> it =key.entrySet().iterator(); while(it.hasNext()){ Entry en =it.next(); r.put(en.getKey(),row[en.getValue()]); } return r; } private void addTableInDocFooterByRow(XWPFTable templateTable, Table data , Map parametersMap) { XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列 List TempTableRows = templateTable.getRows();// 获取模板表格所有行 int tagRowsIndex = 0;// 标签行indexs for (int i = 0, size = TempTableRows.size(); i < size; i++) { String rowText = TempTableRows.get(i).getCell(0).getText();// 获取到表格行的第一个单元格 if (rowText.indexOf("##{foreachRows}##") > -1) { tagRowsIndex = i; break; } } /* 复制模板行和标签行之前的行 */ for (int i = 1; i < tagRowsIndex; i++) { XWPFTableRow newCreateRow = newCreateTable.createRow(); CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行 replaceTableRow(newCreateRow, parametersMap);// 处理不循环标签的替换 } /* 循环生成模板行 */ XWPFTableRow tempRow = TempTableRows.get(tagRowsIndex + 1);// 获取到模板行 for (String[] row: data.data) { XWPFTableRow newCreateRow = newCreateTable.createRow(); CopyTableRow(newCreateRow, tempRow);// 复制模板行 replaceTable(newCreateTable, getMap(data.index,row));//替换标签 } /* 复制模板行和标签行之后的行 */ for (int i = tagRowsIndex + 2; i < TempTableRows.size(); i++) { XWPFTableRow newCreateRow = newCreateTable.createRow(); CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行 replaceTableRow(newCreateRow, parametersMap);// 处理不循环标签的替换 } newCreateTable.removeRow(0);// 移除多出来的第一行 document.createParagraph();// 添加回车换行 } private void addTableInDocFooterByOrigin(XWPFTable templateTable ) { List templateTableRows = templateTable.getRows();// 获取模板表格所有行 XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列 for (int i = 0; i < templateTableRows.size(); i++) { XWPFTableRow newCreateRow = newCreateTable.createRow(); CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行 } newCreateTable.removeRow(0);// 移除多出来的第一行 document.createParagraph();// 添加回车换行 } private void addTableInDocFooterByParas(XWPFTable templateTable, Map parametersMap) { //表格不循环仅简单替换标签 List templateTableRows = templateTable.getRows();// 获取模板表格所有行 XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列 for (int i = 0; i < templateTableRows.size(); i++) { XWPFTableRow newCreateRow = newCreateTable.createRow(); CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行 } newCreateTable.removeRow(0);// 移除多出来的第一行 // document.createParagraph();// 添加回车换行 replaceTable(newCreateTable, parametersMap); } private void addParagraphInDocFooter(XWPFParagraph templateParagraph, List> list, Map parametersMap) { XWPFParagraph createParagraph = document.createParagraph(); // 设置段落样式 createParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr()); // 移除原始内容 for (int pos = 0; pos < createParagraph.getRuns().size(); pos++) { createParagraph.removeRun(pos); } // 添加Run标签 for (XWPFRun s : templateParagraph.getRuns()) { XWPFRun targetrun = createParagraph.createRun(); CopyRun(targetrun, s); } replaceParagraph(createParagraph, parametersMap); } private void replaceParagraph(XWPFParagraph xWPFParagraph, Map parametersMap) { List runs = xWPFParagraph.getRuns(); String xWPFParagraphText = xWPFParagraph.getText(); String regEx = "\\{.+?\\}"; Pattern pattern = Pattern.compile(regEx); Matcher matcher = pattern.matcher(xWPFParagraphText);//正则匹配字符串{****} if (matcher.find()) { // 查找到有标签才执行替换 int beginRunIndex = xWPFParagraph.searchText("{", new PositionInParagraph()).getBeginRun();// 标签开始run位置 int endRunIndex = xWPFParagraph.searchText("}", new PositionInParagraph()).getEndRun();// 结束标签 StringBuffer key = new StringBuffer(); if (beginRunIndex == endRunIndex) { // {**}在一个run标签内 XWPFRun beginRun = runs.get(beginRunIndex); String beginRunText = beginRun.text(); int beginIndex = beginRunText.indexOf("{"); int endIndex = beginRunText.indexOf("}"); int length = beginRunText.length(); if (beginIndex == 0 && endIndex == length - 1) { // 该run标签只有{**} XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex); insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr()); // 设置文本 key.append(beginRunText.substring(1, endIndex)); insertNewRun.setText(getValueBykey(key.toString(),parametersMap)); xWPFParagraph.removeRun(beginRunIndex + 1); } else { // 该run标签为**{**}** 或者 **{**} 或者{**}**,替换key后,还需要加上原始key前后的文本 XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex); insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr()); // 设置文本 key.append(beginRunText.substring(beginRunText.indexOf("{")+1, beginRunText.indexOf("}"))); String textString=beginRunText.substring(0, beginIndex) + getValueBykey(key.toString(),parametersMap) + beginRunText.substring(endIndex + 1); insertNewRun.setText(textString); xWPFParagraph.removeRun(beginRunIndex + 1); } }else { // {**}被分成多个run //先处理起始run标签,取得第一个{key}值 XWPFRun beginRun = runs.get(beginRunIndex); String beginRunText = beginRun.text(); int beginIndex = beginRunText.indexOf("{"); if (beginRunText.length()>1 ) { key.append(beginRunText.substring(beginIndex+1)); } ArrayList removeRunList = new ArrayList<>();//需要移除的run //处理中间的run for (int i = beginRunIndex + 1; i < endRunIndex; i++) { XWPFRun run = runs.get(i); String runText = run.text(); key.append(runText); removeRunList.add(i); } // 获取endRun中的key值 XWPFRun endRun = runs.get(endRunIndex); String endRunText = endRun.text(); int endIndex = endRunText.indexOf("}"); //run中**}或者**}** if (endRunText.length()>1 && endIndex!=0) { key.append(endRunText.substring(0,endIndex)); } //******************************************************************* //取得key值后替换标签 //先处理开始标签 if (beginRunText.length()==2 ) { // run标签内文本{ XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex); insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr()); // 设置文本 insertNewRun.setText(getValueBykey(key.toString(),parametersMap)); xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run }else { // 该run标签为**{**或者 {** ,替换key后,还需要加上原始key前的文本 XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex); insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr()); // 设置文本 String textString=beginRunText.substring(0,beginRunText.indexOf("{"))+getValueBykey(key.toString(),parametersMap); insertNewRun.setText(textString); xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run } //处理结束标签 if (endRunText.length()==1 ) { // run标签内文本只有} XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex); insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr()); // 设置文本 insertNewRun.setText(""); xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run }else { // 该run标签为**}**或者 }** 或者**},替换key后,还需要加上原始key后的文本 XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex); insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr()); // 设置文本 String textString=endRunText.substring(endRunText.indexOf("}")+1); insertNewRun.setText(textString); xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run } //处理中间的run标签 for (int i = 0; i < removeRunList.size(); i++) { XWPFRun xWPFRun = runs.get(removeRunList.get(i));//原始run XWPFRun insertNewRun = xWPFParagraph.insertNewRun(removeRunList.get(i)); insertNewRun.getCTR().setRPr(xWPFRun.getCTR().getRPr()); insertNewRun.setText(""); xWPFParagraph.removeRun(removeRunList.get(i) + 1);//移除原始的run } }// 处理${**}被分成多个run replaceParagraph( xWPFParagraph, parametersMap); }//if 有标签 } /** * 复制表格行XWPFTableRow格式 * * @param target * 待修改格式的XWPFTableRow * @param source * 模板XWPFTableRow */ private void CopyTableRow(XWPFTableRow target, XWPFTableRow source) { int tempRowCellsize = source.getTableCells().size();// 模板行的列数 for (int i = 0; i < tempRowCellsize - 1; i++) { target.addNewTableCell();// 为新添加的行添加与模板表格对应行行相同个数的单元格 } // 复制样式 target.getCtRow().setTrPr(source.getCtRow().getTrPr()); // 复制单元格 for (int i = 0; i < target.getTableCells().size(); i++) { copyTableCell(target.getCell(i), source.getCell(i)); } } /** * 复制单元格XWPFTableCell格式 * * @author Juveniless * @date 2017年11月27日 下午3:41:02 * @param newTableCell * 新创建的的单元格 * @param templateTableCell * 模板单元格 * */ private void copyTableCell(XWPFTableCell newTableCell, XWPFTableCell templateTableCell) { // 列属性 newTableCell.getCTTc().setTcPr(templateTableCell.getCTTc().getTcPr()); if(templateTableCell.getText().indexOf("{noborder}")>-1){ CTTcBorders tblBorders = newTableCell.getCTTc().getTcPr().addNewTcBorders(); tblBorders.addNewLeft().setVal(STBorder.NIL); tblBorders.addNewRight().setVal(STBorder.NIL); tblBorders.addNewTop().setVal(STBorder.NIL); newTableCell.getCTTc().getTcPr().setTcBorders(tblBorders); } // 删除目标 targetCell 所有文本段落 for (int pos = 0; pos < newTableCell.getParagraphs().size(); pos++) { newTableCell.removeParagraph(pos); } // 添加新文本段落 for (XWPFParagraph sp : templateTableCell.getParagraphs()) { XWPFParagraph targetP = newTableCell.addParagraph(); copyParagraph(targetP, sp); } } /** * 复制文本段落XWPFParagraph格式 * * @author Juveniless * @date 2017年11月27日 下午3:43:08 * @param newParagraph * 新创建的的段落 * @param templateParagraph * 模板段落 * */ private void copyParagraph(XWPFParagraph newParagraph, XWPFParagraph templateParagraph) { // 设置段落样式 newParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr()); // 添加Run标签 for (int pos = 0; pos < newParagraph.getRuns().size(); pos++) { newParagraph.removeRun(pos); } for (XWPFRun s : templateParagraph.getRuns()) { XWPFRun targetrun = newParagraph.createRun(); CopyRun(targetrun, s); } } /** * 复制文本节点run * @author Juveniless * @date 2017年11月27日 下午3:47:17 * @param newRun * 新创建的的文本节点 * @param templateRun * 模板文本节点 * */ private void CopyRun(XWPFRun newRun, XWPFRun templateRun) { newRun.getCTR().setRPr(templateRun.getCTR().getRPr()); // 设置文本 newRun.setText(templateRun.text()); } private void replaceTableRow(XWPFTableRow tableRow, Map parametersMap) { List tableCells = tableRow.getTableCells(); for (XWPFTableCell xWPFTableCell : tableCells) { List paragraphs = xWPFTableCell.getParagraphs(); for (XWPFParagraph xwpfParagraph : paragraphs) { replaceParagraph(xwpfParagraph, parametersMap); } } } private void replaceTable(XWPFTable xwpfTable, Map parametersMap){ List rows = xwpfTable.getRows(); for (XWPFTableRow xWPFTableRow : rows ) { List tableCells = xWPFTableRow.getTableCells(); for (XWPFTableCell xWPFTableCell : tableCells ) { List paragraphs2 = xWPFTableCell.getParagraphs(); for (XWPFParagraph xWPFParagraph : paragraphs2) { replaceParagraph(xWPFParagraph, parametersMap); } } } } private String getValueBykey(String key, Map map) { String returnValue=""; if (key != null) { key = key.trim(); try { returnValue=map.get(key)!=null ? map.get(key).toString() : ""; } catch (Exception e) { returnValue=""; } } // System.out.println(key+":" + returnValue); return returnValue; } public static XWPFTableRow insertRow(XWPFTable table, int copyrowIndex, int newrowIndex,int fontSize,String fontFamily) { // 在表格中指定的位置新增一行 XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex); // 获取需要复制行对象 XWPFTableRow copyRow = table.getRow(copyrowIndex); //复制行对象 targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr()); //或许需要复制的行的列 List copyCells = copyRow.getTableCells(); //复制列对象 XWPFTableCell targetCell = null; for (int i = 0; i < copyCells.size(); i++) { XWPFTableCell copyCell = copyCells.get(i); targetCell = targetRow.addNewTableCell(); targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr()); if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) { targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr()); if (copyCell.getParagraphs().get(0).getRuns() != null && copyCell.getParagraphs().get(0).getRuns().size() > 0) { XWPFRun cellR = targetCell.getParagraphs().get(0).createRun(); cellR.setText(copyCell.getParagraphs().get(0).getText()); cellR.setBold(copyCell.getParagraphs().get(0).getRuns().get(0).isBold()); cellR.setFontSize(fontSize); cellR.setFontFamily(fontFamily); } } } return targetRow; } public static void setCell(XWPFTableCell targetCell, String wrapped_keyword,String content, int fontSize, String fontFamily,boolean isCenter) { List paragraphs = targetCell.getParagraphs(); for (int i = 0; i < paragraphs.size(); i++) { XWPFParagraph paragraph = paragraphs.get(i); String text = paragraph.getText(); if (text.contains(wrapped_keyword)) { String after_replace = text.replace(wrapped_keyword, StringUtils.isBlank(content)?"":content); targetCell.removeParagraph(i); XWPFParagraph newP = targetCell.addParagraph(); if (isCenter) newP.setAlignment(ParagraphAlignment.CENTER); XWPFRun run = newP.createRun(); run.setText(after_replace); run.setFontSize(fontSize); run.setFontFamily(fontFamily); } } } public XWPFDocument getDocument() { return document; } public void setDocument(XWPFDocument document) { this.document = document; } // public void wordConvertPdf(String fileURI) throws IOException { // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // document.write(baos); // ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray()); // // FileOutputStream fileOutputStream = new FileOutputStream(fileURI); // // IConverter converter = LocalConverter.builder().build(); // converter.convert(in).as(DocumentType.DOCX).to(fileOutputStream).as(DocumentType.PDF).execute(); // fileOutputStream.close(); // // } // // // public void wordConvertPdf(String docxPath,String savePdfPath) throws IOException { // try { //// InputStream inputStream = WordTemplate.class.getClassLoader().getResourceAsStream ("license.xml"); // License license = new License(); // ClassPathResource resource = new ClassPathResource("license.xml"); // InputStream inputStream = resource.getInputStream(); // license.setLicense(inputStream); // com.aspose.words.Document document = new com.aspose.words.Document(docxPath); // FileOutputStream fileOutputStream = new FileOutputStream(new File(savePdfPath)); // document.deepClone().save(fileOutputStream, SaveFormat.PDF); // inputStream.close(); // fileOutputStream.close(); // } catch (Exception e) { // e.printStackTrace(); // } // // // } /** * @Description: 替换指定索引表单,指定字体和字体大小 * @date 2021/8/30 8:49 */ public void replace(int targetTable,Map tables,Map mergeTables, Map simpleData,int fontSize,String fontFamily) { //table标识集合 Set tableFlags = tables.keySet(); Set mergeTableFlags = mergeTables.keySet(); List bodyElements = document.getBodyElements(); for (IBodyElement bodyElement : bodyElements) { if (bodyElement.getElementType() == BodyElementType.TABLE) { IBody body = bodyElement.getBody(); //第一表单 XWPFTable table = body.getTableArray(targetTable); List rows = table.getRows(); for (int i = 0; i < rows.size(); i++) { XWPFTableRow currentRow = rows.get(i); List currentRowCells = currentRow.getTableCells(); for (XWPFTableCell currentCell : currentRowCells) { String text = currentCell.getText(); for (int k = 0; k < text.length(); k++) { int left_flag = text.indexOf(replace_flag_left,k); int right_flag = text.indexOf(replace_flag_right,k); if (left_flag != -1 && right_flag != -1) { String keyword = text.substring(left_flag + replace_flag_left.length(), right_flag); String wrapped_keyword = replace_flag_left + keyword + replace_flag_right; if (simpleData.containsKey(keyword)) { String content = simpleData.get(keyword); WordTemplate.setCell(currentCell,wrapped_keyword,content,fontSize,fontFamily,false); } k = right_flag; } } if (tableFlags.contains(text)) { int templateRowIndex = i + 1; WordTemplate.Table workerTable = tables.get(text); List tableData = workerTable.data; String[] fields = workerTable.fields; Map index = workerTable.index; for (int j = 0; j < tableData.size(); j++) { //行数据 String[] tableRowData = tableData.get(j); //新增行为数据替换行 XWPFTableRow targetRow = WordTemplate .insertRow(table, templateRowIndex, templateRowIndex + 1, fontSize,fontFamily); //单独替换数据 for (XWPFTableCell targetCell : targetRow.getTableCells()) { String wordText = targetCell.getText(); for (int m = 0; m < wordText.length(); m++) { int left_flag = wordText.indexOf(replace_flag_left,m); int right_flag = wordText.indexOf(replace_flag_right,m); if (left_flag != -1 && right_flag != -1) { String keyword = wordText.substring(left_flag + replace_flag_left.length(), right_flag); String wrapped_keyword = replace_flag_left + keyword + replace_flag_right; if (index.get(keyword) != null) { Integer fieldIndex = index.get(keyword); String content = tableRowData[fieldIndex]; WordTemplate.setCell(targetCell,wrapped_keyword,content,fontSize,fontFamily,true); } } } } } //table标识行函数删除 table.removeRow(i); //模板行删除 table.removeRow(i); } //合并表 if (mergeTableFlags.contains(text)) { int templateRowIndex = i + 1; MergeTable mergeTable = mergeTables.get(text); List tableData = mergeTable.data; String[] fields = mergeTable.fields; String[] mergeFields = mergeTable.mergeFields; HashSet set = new HashSet<>(Arrays.asList(mergeFields)); Map index = mergeTable.index; for (int l = 0; l < tableData.size(); l++) { //行数据 String[] tableRowData = tableData.get(l); //新增行为数据替换行 XWPFTableRow targetRow = WordTemplate .insertRow(table, templateRowIndex, templateRowIndex + 1, fontSize,fontFamily); //单独替换数据 for (XWPFTableCell targetCell : targetRow.getTableCells()) { String wordText = targetCell.getText(); for (int m = 0; m < wordText.length(); m++) { int left_flag = wordText.indexOf(replace_flag_left,m); int right_flag = wordText.indexOf(replace_flag_right,m); if (left_flag != -1 && right_flag != -1) { String keyword = wordText.substring(left_flag + replace_flag_left.length(), right_flag); //合并项 if (set.contains(keyword)) { //因为是头插,所以合并的restart为最后一个 if (l == tableData.size()-1 ) targetCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART); else targetCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE); } //替换 String wrapped_keyword = replace_flag_left + keyword + replace_flag_right; if (index.get(keyword) != null) { Integer fieldIndex = index.get(keyword); String content = tableRowData[fieldIndex]; WordTemplate.setCell(targetCell,wrapped_keyword,content,fontSize,fontFamily,false); } } } } } //table标识行函数删除 table.removeRow(i); //模板行删除 table.removeRow(i); } } } } } } public void replaceQRCode(String qrCodeSavePath,String info,int width,int height,int leftOffset,int topOffset) throws IOException, InvalidFormatException, InterruptedException { Image image = QRCode.generateQRCode(info); String QRCodeUrl = qrCodeSavePath + info + "_" + "QRCode.png"; File file = new File(QRCodeUrl); if (!file.exists()) {file.createNewFile();} ImageIO.write((RenderedImage) image, "png", file); FileInputStream in = new FileInputStream(file); List paragraphs = document.getParagraphs(); for (int i = 0; i < paragraphs.size(); i++) { XWPFParagraph paragraph = paragraphs.get(i); List runs = paragraph.getRuns(); for (int l = 0; l < runs.size(); l++) { XWPFRun run = runs.get(l); String text = run.text(); if (text.equals("#{qrcode}#")) { paragraph.removeRun(l);//同时把正文两字移除 XWPFRun xwpfRun = paragraph.insertNewRun(l); xwpfRun.addPicture(in, XWPFDocument.PICTURE_TYPE_PNG, "QRCode.png", Units.toEMU(width), Units.toEMU(height)); //浮于文字上方 CTDrawing drawing= xwpfRun.getCTR().getDrawingArray(0); CTGraphicalObject go= drawing.getInlineArray(0).getGraphic(); Random random= new Random(); int number = random.nextInt(999) + 1; CTAnchor anchor1 = getAnchorWithGraphic(go, "Seal" +number, Units.toEMU(width), Units.toEMU(height),//图片大小 Units.toEMU(leftOffset), Units.toEMU(topOffset), false); drawing.setAnchorArray(new CTAnchor[]{anchor1});//添加浮动属性 drawing.removeInline(0);//删除行内属性//添加签名图片 } } } in.close(); } public static String formatTime(Date date, SimpleDateFormat sdf) { String dateStr = " 年 月 日 时 分"; if (sdf == null) { sdf = WordTemplate.sdf; } if (date != null) dateStr = sdf.format(date); return dateStr; } public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject, String deskFileName,int width, int height,int leftOffset, int topOffset, boolean behind) { String anchorXML = "" + "" + "" + "" + leftOffset + "" + "" + "" + "" + topOffset + "" + "" + "" + "" + "" + "" + ""; CTDrawing drawing= null; try{ drawing= CTDrawing.Factory.parse(anchorXML); }catch(XmlException e) { e.printStackTrace(); } assert drawing != null; CTAnchor anchor= drawing.getAnchorArray(0); anchor.setGraphic(ctGraphicalObject); return anchor; } public void generateSelfCheckTableParam(int targetTable,Map>> taskTypeMergeMap ,int fontSize,String fontFamily) { Set templateTasktypeFlag = taskTypeMergeMap.keySet(); List bodyElements = document.getBodyElements(); for (IBodyElement bodyElement : bodyElements) { if (bodyElement.getElementType() == BodyElementType.TABLE) { IBody body = bodyElement.getBody(); //第一表单 XWPFTable table = body.getTableArray(targetTable); List rows = table.getRows(); for (int i = 0; i < rows.size(); i++) { XWPFTableRow currentRow = rows.get(i); List currentRowCells = currentRow.getTableCells(); for (XWPFTableCell currentCell : currentRowCells) { String text = currentCell.getText(); if (templateTasktypeFlag.contains(text)) { Map> mergeTableMap = taskTypeMergeMap.get(text); //如果包tasktype 做一件事(循环生成多个作业table) 规则为tasktype所在行和下面3行 //总体规则:往第一个模板后面插,最后把第一个模板删除 //当前行:i行 int targetRowPosition = i + 4; for (Map.Entry> entry : mergeTableMap.entrySet()) { String currentTaskType = entry.getKey(); List mergeTableFlags = entry.getValue(); for (int j = mergeTableFlags.size() - 1; j >= 0; j--) { String mergeTableFlag = mergeTableFlags.get(j); //生成一个作业的4行表格 for (int m = 3; m >= 2; m--) { WordTemplate .insertRow(table, i + m, targetRowPosition, fontSize, fontFamily); XWPFTableRow targetRow = rows.get(targetRowPosition); List tableCells = targetRow.getTableCells(); for (XWPFTableCell cell : tableCells) { String mergeTableFlagOriginal = "mergeTable"; if (mergeTableFlagOriginal.equals(cell.getText())) { WordTemplate.setCell(cell,mergeTableFlagOriginal,mergeTableFlag,fontSize,fontFamily,false); } } } } for (int k = 1; k >= 0; k--) { WordTemplate .insertRow(table, i + k, targetRowPosition, fontSize, fontFamily); XWPFTableRow targetTitleRow = rows.get(targetRowPosition); List tableCells = targetTitleRow.getTableCells(); for (XWPFTableCell cell : tableCells) { if (text.equals(cell.getText())) { WordTemplate.setCell(cell,text,currentTaskType,fontSize,fontFamily,false); } } } } //模板行删除 4行 { table.removeRow(i); table.removeRow(i); table.removeRow(i); table.removeRow(i); } } } } } } } public void generateOwnTypeAndAttrs(int targetTable, Map>> typeMap, int fontSize, String fontFamily) { Set typeFlagSet = typeMap.keySet(); List bodyElements = document.getBodyElements(); for (IBodyElement bodyElement : bodyElements) { if (bodyElement.getElementType() == BodyElementType.TABLE) { IBody body = bodyElement.getBody(); XWPFTable table = body.getTableArray(targetTable); List rows = table.getRows(); for (int i = 0; i < rows.size(); i++) { XWPFTableRow currentRow = rows.get(i); List currentTableCells = currentRow.getTableCells(); for (XWPFTableCell currentCell : currentTableCells) { String text = currentCell.getText(); if (typeFlagSet.contains(text)) { currentCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); //模板行位置 int templateRowPosition = i + 1; //生成行位置 int targetRowPosition = i + 2; Map> allTypeMap = typeMap.get(text); for (Map.Entry> entry : allTypeMap.entrySet()) { String currentType = entry.getKey(); List currentTypeAttrList = entry.getValue(); //计算要生成几行 每行两个属性 int rowLength = new Double(Math.ceil((double) currentTypeAttrList.size() / 2)).intValue(); //如果是奇数个属性就补全 if (currentTypeAttrList.size() % 2 == 1) currentTypeAttrList.add(currentTypeAttrList.size()-1,new Attribute("", "")); for (int m = 0; m < rowLength ; m++) { WordTemplate.insertRow(table, templateRowPosition, targetRowPosition, fontSize, fontFamily); XWPFTableRow targetRow = rows.get(targetRowPosition); //首个单元格设置作业类型 List targetTableCells = targetRow.getTableCells(); for (int j = 0; j < targetTableCells.size(); j++) { assert targetTableCells.size()%2 == 1; XWPFTableCell targetCell = targetTableCells.get(j); if (j == 0) { setContent(targetCell, currentType,fontSize,fontFamily); } if (j%2 == 1){ setContent(targetCell, currentTypeAttrList.get(currentTypeAttrList.size() - 1).attribute, fontSize, fontFamily); setContent(targetTableCells.get(j+1), currentTypeAttrList.get(currentTypeAttrList.size() - 1).value, fontSize, fontFamily); currentTypeAttrList.remove(currentTypeAttrList.size() - 1); } } } //合并cell的第一个type //合并行第一行 就是生成行位置 //合并行末尾行 int lastMergePosition = templateRowPosition + rowLength; for (int n = targetRowPosition; n <= lastMergePosition; n++) { XWPFTableRow xwpfTableRow = rows.get(n); XWPFTableCell targetCell = xwpfTableRow.getCell(0); if (n == targetRowPosition ) targetCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART); else targetCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE); } } //删除模板行 table.removeRow(i); table.removeRow(i); } } } } } } public void replaceAutoGraph(String taskPathPrefix , Map nameMapGraph, int width, int height,int leftOffset, int topOffset) throws IOException, InvalidFormatException { Set keys = nameMapGraph.keySet(); List bodyElements = document.getBodyElements(); for (IBodyElement bodyElement : bodyElements) { if (bodyElement.getElementType() == BodyElementType.TABLE) { IBody body = bodyElement.getBody(); List tables = body.getTables(); for (XWPFTable table : tables) { List rows = table.getRows(); for (XWPFTableRow row : rows) { for (XWPFTableCell cell : row.getTableCells()) { List paragraphs = cell.getParagraphs(); for (int i = 0; i < paragraphs.size(); i++) { XWPFParagraph paragraph = paragraphs.get(i); List runs = paragraph.getRuns(); for (int j = 0; j < runs.size(); j++) { XWPFRun run = runs.get(j); String text = run.text(); if (keys.contains(text)) { if (StringUtils.isNotBlank(nameMapGraph.get(text))) { String url = taskPathPrefix + nameMapGraph.get(text); FileInputStream in = new FileInputStream(url); paragraph.removeRun(j);//同时把正文两字移除 paragraph.setAlignment(ParagraphAlignment.CENTER); XWPFRun xwpfRun = paragraph.insertNewRun(j); xwpfRun.addPicture(in, getPictureFormat(url), url, Units.toEMU(width), Units.toEMU(height)); //浮于文字上方 CTDrawing drawing= xwpfRun.getCTR().getDrawingArray(0); CTGraphicalObject go= drawing.getInlineArray(0).getGraphic(); Random random= new Random(); int number = random.nextInt(999) + 1; CTAnchor anchor1 = getAnchorWithGraphic(go, "Seal" +number, Units.toEMU(width), Units.toEMU(height),//图片大小 0, 0, true); drawing.setAnchorArray(new CTAnchor[]{anchor1});//添加浮动属性 drawing.removeInline(0);//删除行内属性//添加签名图片 in.close(); }else{ paragraph.removeRun(j);//同时把正文两字移除 paragraph.setAlignment(ParagraphAlignment.CENTER); XWPFRun xwpfRun = paragraph.insertNewRun(j); xwpfRun.setText(" "); } } } } } } } } } } private void setContent(XWPFTableCell targetCell, String content, int fontSize, String fontFamily) { XWPFRun run = targetCell.getParagraphs().get(0).createRun(); run.setText(content); run.setFontFamily(fontFamily); run.setFontSize(fontSize); } public static int getPictureFormat(String imgFile) { int format; if (imgFile.endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF; else if (imgFile.endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF; else if (imgFile.endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT; else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG; else if (imgFile.endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG; else if (imgFile.endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB; else if (imgFile.endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF; else if (imgFile.endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF; else if (imgFile.endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS; else if (imgFile.endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP; else if (imgFile.endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG; else { System.err.println("Unsupported picture: " + imgFile + ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg"); System.err.println("不支持的图片格式: " + imgFile + ". 仅支持 emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg 格式的图片"); format = -1; } return format; } }