Word2007 format, similar substitutes for $ {name} character format, support word embedded in tabular form, as follows:
package com.authweb.tools.bookmarkprocess; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.xwpf.usermodel.*; import org.apache.xmlbeans.impl.piccolo.io.FileFormatException; import java.io.*; import java.lang.reflect.Field; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import static feign.Util.toByteArray; /** * Created by clyyan on 2019/7/2 15:15. */ public class Word2007 { private String wordPath = ""; private String tempFilePath = ""; private Object obj = null; Map<String, Object> map = new HashMap<String, Object>(); /* path:文件路径 dataSource/objectMap:数据源. */ public Word2007(String path, String userAccount, Object dataSource, Map<String, Object> objectMap) throws IOException { File file = new File(path); if (file.exists() == false || file.isFile() == false) { the throw new new a FileNotFoundException ( "file does not exist" ); } the InputStream IS = new new the FileInputStream (File); byte [] bytes = new new byte [10 ;] IF (is.read (bytes, 0, bytes.length) == -1 ) { is.close (); the throw new new FileFormatException ( "file format error, this document only docx file parsing" ); } String fileCode = bytesToHexString (bytes) .toLowerCase (); IF (fileCode.length ()>. 1 ) { IF (fileCode.equals ( "504b0304140006000800") == to false) { Is.close (); the throw new new FileFormatException ( "file format error, this document only docx file parsing" ); } } is.close (); wordPath = path; obj = the dataSource; File testFile = new new File (path .substring (0, path.lastIndexOf ( "\\ ")) + "\\" + " document -" + UserAccount + "\\" ); IF (! ) {testFile.exists () testFile.mkdirs (); } the Tempfilepath= path.substring(0, path.lastIndexOf("\\")) + "\\" + "文书-" + userAccount + "\\" + path.substring(path.lastIndexOf("\\") + 1); if (dataSource != null) { pickFields(); } else { this.map = objectMap; } } public String parseTemplate() { try { InputStream is = new FileInputStream(wordPath); XWPFDocument doc = new XWPFDocument(OPCPackage.open(is)); List<XWPFParagraph> list = doc.getParagraphs(); for (int i = 0; i < list.size(); i++) { XWPFParagraph graph = list.get(i); replaceInXWPFParagraph(graph, map); } replaceTables(map, doc); OutputStream os = new FileOutputStream(tempFilePath); doc.write(os); os.flush(); close(os); close(is); } catch (Exception ex) { System.out.print(ex.getStackTrace()); } return tempFilePath; } private void replaceInXWPFParagraph(XWPFParagraph para, Map<String, Object> params) { List<XWPFRun> runs = null; Matcher matcher; String runText = ""; if (matcher(para.getParagraphText()).find()) { runs = para.getRuns(); if (runs.size() > 0) { int j = runs.size(); for (int i = 0; i < j; i++) { XWPFRun run = runs.get(i); String i1 =run.toString (); runText + = I1; } } Matcher = Matcher (runText); IF (matcher.find ()) { the while ((= Matcher . Matcher (runText)) Find ()) { runText = String.valueOf (params.get (Matcher.group (. 1 ))); } // data source is not the skip, so as to check IF (runText = "null" && runs.size ()> 0! {) Boolean Handler = to false ; for ( int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i); String temp = run.toString(); if (handler == false && temp.indexOf("$") >= 0) { handler = true; } if (handler == true) { if (temp.equals("$") || temp.indexOf("$") == 0) { if (temp.indexOf("}") >= 0) { run.setText(runText, 0); handler = false; } else { run.setText("", 0); } continue; } if (temp.indexOf("}") < 0) { run.setText("", 0); continue; } if (temp.indexOf("}") >= 0) { run.setText(runText, 0); handler = false; } } } } } } } private void pickFields() { Class dataClass = (Class) obj.getClass(); Field[] fs = dataClass.getDeclaredFields(); for (int i = 0; i < fs.length; i++) { Field f = fs[i]; f.setAccessible(true); Object val = new Object(); try { val = f.get(obj); map.put(f.getName(), val); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } private byte[] generalFileContent() throws IOException { InputStream is = new FileInputStream(tempFilePath); byte[] data = toByteArray(is); is.close(); return data; } private void close(InputStream is) { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } private void close(OutputStream os) { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } private String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (null == src || src.length < 1) return null; for (byte b : src) { int v = b & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) stringBuilder.append(0); stringBuilder.append(hv); } return stringBuilder.toString(); } private static Matcher matcher(String str) { Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(str); return matcher; } private void replaceTable(Map<String, Object> params, XWPFTable table) { int count = table.getNumberOfRows(); for (int i = 0; i < count; i++) { XWPFTableRow row = table.getRow(i); List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List<XWPFParagraph> list = cell.getParagraphs(); for (int j = 0; j < list.size(); j++) { replaceInXWPFParagraph(list.get(j), params); } } } } private void replaceTables(Map<String, Object> params, XWPFDocument document) { Iterator<XWPFTable> itTable = document.getTablesIterator(); while (itTable.hasNext()) { XWPFTable table = itTable.next(); replaceTable(params, table); } } }