/* * Copyright (c) 2017 西安才多信息技术有限责任公司。 * 项目名称:dev * 文件名称:DocxTemplateUtils.java * 日期:17-10-11 下午2:18 * 作者:yangyan * */ package com.deyatong.common.util; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * WORD DOCX 文件变量替换输出工具类 */ public class DocxTemplateUtils { Logger logger = LoggerFactory.getLogger(getClass()); /** * 变量替换符号的正则,用来找到 ${xxx} 这样的内容,并实现替换 */ Pattern compile = Pattern.compile("(\\$\\{([^\\}]*)\\})"); private final Map<String, ?> params; //数据填充对象 InputStream is; //读入模板文件的流 XWPFDocument doc; //内存中构建的文档对象 /** * 使用文件路径和变量集合创建 * * @param templateDocxFile * @param params */ public DocxTemplateUtils(String templateDocxFile, Map<String, ?> params) { this.params = params; try { is = new FileInputStream(templateDocxFile); doc = new XWPFDocument(is); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 使用文件和和变量集合创建 * * @param templateDocxFile * @param params */ public DocxTemplateUtils(File templateDocxFile, Map<String, ?> params) { this.params = params; try { is = new FileInputStream(templateDocxFile); doc = new XWPFDocument(is); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 使用模板读入的流和变量集合创建 * * @param templateDocxFileInputStream * @param params */ public DocxTemplateUtils(InputStream templateDocxFileInputStream, Map<String, ?> params) { this.params = params; try { is = templateDocxFileInputStream; doc = new XWPFDocument(is); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 此类为poi操作word模板的工具类 **/ public XWPFDocument getDoc() { return doc; } /** * 替换所有段落中的变量 */ public void replaceInPara() { Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator(); XWPFParagraph para; while (iterator.hasNext()) { para = iterator.next(); this.replaceInPara(para); } } /** * 替换传入段落里面的变量 * * @param para 要替换的段落 */ private void replaceInPara(XWPFParagraph para) { String paragraphText = para.getParagraphText(); int start = paragraphText.indexOf("${"); int end = paragraphText.indexOf("}"); if (start == -1 && end == -1) { //段落中没有变量直接跳过 logger.warn("没开始,没结束,直接跳过:" + paragraphText); return; } boolean isStart = false; boolean isEnd = false; StringBuilder varName = null; List<XWPFRun> runs; Matcher matcher; runs = para.getRuns(); //不同的文字片段可能有不同的样式 logger.info("整段:" + paragraphText); // for (int i = 0; i < runs.size(); i++) { // XWPFRun run = runs.get(i); // String runText = run.toString().trim(); // System.out.println(runText); // } for (int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i); String runText = run.toString().trim(); logger.debug(">>>处理文字片段:" + runText); String tail = ""; if (runText.trim().length() == 0) { continue; } if (varName == null) { varName = new StringBuilder(); } int s = runText.indexOf("${"); if (s > -1) { //有开始 int n = runText.indexOf("}", s); if (n != -1) { //有结束 varName.append(runText.substring(s, n + 1)); isEnd = true; if (runText.indexOf("${", n) != -1) { //一行内是否有第二个变量开启 isStart = true; } tail = runText.substring(n + 1); } else { //没结束 isStart = true; isEnd = false; varName.append(runText.substring(s)); run.setText("", 0); } } else { //没开始 if (isStart) { //之前开始了 int n = runText.indexOf("}"); if (n == -1) { //没结束 varName.append(runText); run.setText("", 0); } else { //结束 isStart = false; varName.append(runText.substring(0, n + 1)); if (runText.indexOf("${", n) != -1) { //一行内是否有第二个变量开启 isStart = true; tail = runText.substring(n + 1); } isEnd = true; } } } if (isEnd) { String s1 = varName.toString(); logger.warn("拼接结果:" + s1); Object o = params.get(s1); String value = o == null ? "" : o.toString(); run.setText(value + tail, 0); varName = null; isEnd = false; } // if (s == -1) { //如果没有开始标记后面的就不用执行了 // break; // } //文字替换处理 matcher = compile.matcher(runText); while (matcher.find()) { String group = matcher.group(1); logger.debug("----找到变量:" + group + String.format(",文字片段内位置:(%s-%s)", matcher.start(), matcher.end())); Object o = params.get(group); String replacement = ""; if (o != null) { if (o instanceof List) { //替换的内容 logger.debug("----变量替换成为:" + StringUtils.join(o)); run.setText("", 0); List list = (List) o; for (Object o1 : list) { run.addCarriageReturn(); run.setText(o1.toString()); } break; } else { replacement = o.toString(); //替换的内容 runText = matcher.replaceFirst(replacement); logger.debug("----变量替换成为:" + replacement); run.setText(runText, 0); logger.debug(">>>片段替换成为:" + runText); } } } } } /** * 替换表格里面的变量 */ public void replaceInTable() { Iterator<XWPFTable> iterator = doc.getTablesIterator(); XWPFTable table; List<XWPFTableRow> rows; List<XWPFTableCell> cells; List<XWPFParagraph> paras; while (iterator.hasNext()) { table = iterator.next(); rows = table.getRows(); for (XWPFTableRow row : rows) { cells = row.getTableCells(); for (XWPFTableCell cell : cells) { paras = cell.getParagraphs(); for (XWPFParagraph para : paras) { this.replaceInPara(para); } } } } } /** * 关闭输入流 */ public void closeInputStream() { if (is != null) { try { is.close(); } catch (Exception e) { e.printStackTrace(); } } } /** * 关闭输出流 * * @param os */ public void closeOutputStream(OutputStream os) { if (os != null) { try { os.close(); } catch (Exception e) { e.printStackTrace(); } } } public void addTablesRows(List<List<String>> data, int tableIndex, int rowIndex) { List<XWPFTable> list = doc.getTables(); System.out.println("----" + list.size()); XWPFTable xt = list.get(tableIndex); if (rowIndex < 0 || (rowIndex + 1) > xt.getNumberOfRows()) { rowIndex = xt.getNumberOfRows() - 1; } XWPFTableRow row1 = xt.getRow(rowIndex + 1); if (row1 == null) { row1 = xt.createRow(); addTablesRows(data, tableIndex, rowIndex); return; } for (int i = 0; i < data.size(); i++) { XWPFTableRow row2 = xt.getRow(rowIndex + i); if (row2 == null) { row2 = xt.createRow(); } List<XWPFTableCell> cells = row2.getTableCells(); List<String> clist = data.get(i); for (int k = 0; k < clist.size(); k++) { XWPFTableCell cell = row2.getCell(k); cell.setText(clist.get(k)); } } } }
了解 工作生活心情记忆 的更多信息
Subscribe to get the latest posts sent to your email.