Word模板内容修改
1.java代码
package com.sicdt.sicsign.web.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.xwpf.converter.core.XWPFConverterException; import org.apache.poi.xwpf.converter.pdf.PdfConverter; import org.apache.poi.xwpf.converter.pdf.PdfOptions; import org.apache.poi.xwpf.usermodel.UnderlinePatterns; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; 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; /** * * @author zhenwei.shi * */ public class DocxUtils { //word模板的标签为【string】 private static final String FLAG_L = "【";//标签左侧 private static final String FLAG_R = "】";//标签右侧 //private static final String REGEX = "(\w|\W)*\【\w+\】(\w|\W)*";//正则匹配*【*】*类型字符串 public static final String NULL_REPLACE = " / ";//如果没有替换的将显示" " public static final String DOWNLOAD_REPLACE = " ";//下载替换word模板标签 public static final String PREVIEW_REPLACE = " / ";//预览替换word模板标签 /** * <br> * 描 述: doc内容改变 <br> * 作 者: shizhenwei <br> * 历 史: (版本) 作者 时间 注释 * * @param is * doc文档模板 * @param params * key value 将模板里的可以替换为响应VALUE * @return * @throws IOException */ public static byte[] docContentChange(InputStream is, Map<String, String> params) throws IOException { if(null==params){ params = new HashMap<String,String>(); } HWPFDocument document = new HWPFDocument(is); Range range = document.getRange(); Set<String> keys = params.keySet(); for (String key : keys) { range.replaceText(key.toString(), params.get(key)); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); document.write(baos); byte[] bytes = baos.toByteArray(); document.close(); baos.close(); return bytes; } /** * <br>描 述: 改变word内容,讲word标签【*】替换为指定内容 * <br>作 者: shizhenwei * <br>历 史: (版本) 作者 时间 注释 * @return * @throws IOException * @throws XWPFConverterException */ public static byte[] docxContentChange(InputStream is,Map<String,String> params) throws XWPFConverterException, IOException{ return docxContentChange(is,params,NULL_REPLACE); } /** * <br>描 述: docx内容改变 * <br>作 者: shizhenwei * <br>历 史: (版本) 作者 时间 注释 * @param is docx文档模板 * @param params key value 将模板里的可以替换为响应VALUE * @return * @throws IOException * @throws XWPFConverterException */ public static byte[] docxContentChange(InputStream is,Map<String,String> params,String replace) throws XWPFConverterException, IOException{ if(null==params){ params = new HashMap<String,String>(); } XWPFDocument document = new XWPFDocument(is); //替换段落内容 List<XWPFParagraph> list = document.getParagraphs(); for(XWPFParagraph paragraph : list){ replaceParagraph(paragraph, params, replace,true); } //替换表格内容 List<XWPFTable> tableList = document.getTables(); for(XWPFTable table : tableList){ List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List<XWPFParagraph> paras = cell.getParagraphs(); for (XWPFParagraph para : paras) { replaceParagraph(para, params, replace,false); } } } } ByteArrayOutputStream baos = new ByteArrayOutputStream(); document.write(baos); byte[] bytes = baos.toByteArray(); document.close(); baos.close(); return bytes; } /** * <br>描 述: 将docx字节数组流转换为pdf字节数组流 * <br>作 者: shizhenwei * <br>历 史: (版本) 作者 时间 注释 * @param docxBytes docx文档字节数组 * @return * @throws XWPFConverterException * @throws IOException * 注:需在部署系统安装word对应的中文字体 */ public static byte[] docx2pdf(byte[] docxBytes) throws XWPFConverterException, IOException{ PdfOptions options = PdfOptions.create(); XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(docxBytes)); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfConverter.getInstance().convert(document, baos, options); return baos.toByteArray(); } /** * <br>描 述: 将Word模板流改变内容后转换为pdf字节数组流 * <br>作 者: shizhenwei * <br>历 史: (版本) 作者 时间 注释 * @param is docx文档输入流 * @param params key value 将模板里的可以替换为响应VALUE * @return * @throws IOException * @throws XWPFConverterException * * 注:需在部署系统安装word对应的中文字体 */ public static byte[] docx2pdf(InputStream is,Map<String, String> params,String replace) throws XWPFConverterException, IOException{ if(null==params){ params = new HashMap<String,String>(); } XWPFDocument document = new XWPFDocument(is); //替换段落内容 List<XWPFParagraph> list = document.getParagraphs(); for(XWPFParagraph paragraph : list){ replaceParagraph(paragraph, params, replace,true); } //替换表格内容 List<XWPFTable> tableList = document.getTables(); for(XWPFTable table : tableList){ List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List<XWPFParagraph> paras = cell.getParagraphs(); for (XWPFParagraph para : paras) { replaceParagraph(para, params, replace,false); } } } } ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfOptions options = PdfOptions.create(); PdfConverter.getInstance().convert(document, baos, options); byte[] bytes = baos.toByteArray(); document.close(); baos.close(); return bytes; } //在替换的值左右延长两个空格长度 public static String getReplaceValue(String old){ return " "+old+" "; } /** * <br>描 述: 替换段落内容 * <br>作 者: shizhenwei * <br>历 史: (版本) 作者 时间 注释 * @param paragraph * @param params * @param replace * @param underline * @return */ public static String replaceParagraph(XWPFParagraph paragraph,Map<String, String> params,String replace,boolean underline){ //字符串过长,调用matches方法报堆溢出错误 /*String regex = REGEX;//【string】匹配 if(!paragraph.getText().matches(regex)){ continue; }*/ //改为contains String pghTxt = paragraph.getText(); if(!(pghTxt.contains(FLAG_L)&&pghTxt.contains(FLAG_R))){ return null; } List<XWPFRun> runs = paragraph.getRuns(); String key = ""; boolean left = false;//left=true 说明有【 boolean right = false;//right=true 说明有】 //这里没有做到百分百细致化,如果run中出现这样的形式 *【*】*】或者*】*【*】,将会存在问题,所以要监管好模板。 for(int i=0; i<runs.size(); i++){ XWPFRun run = runs.get(i); String runText = run.text(); if(runText.contains(FLAG_L) && runText.contains(FLAG_R)){ key = runText.substring(runText.indexOf(FLAG_L)+1,runText.indexOf(FLAG_R)); String text = runText.replaceAll(FLAG_L+key+FLAG_R, StringUtils.isEmpty(params.get(key))?replace:getReplaceValue(params.get(key))); run.setText(text,0); key = ""; addUnderline(run, underline); }else if(runText.contains(FLAG_L)){ left = true; String temp = runText.substring(runText.indexOf(FLAG_L)+1); key += temp; String text = runText.replaceAll(FLAG_L+temp, ""); run.setText(text,0); addUnderline(run, underline); }else if(runText.contains(FLAG_R)){ right = true; String temp = runText.substring(0,runText.indexOf(FLAG_R)); key += temp; String text = runText.replaceAll(temp+FLAG_R, (StringUtils.isEmpty(params.get(key))?replace:getReplaceValue(params.get(key)))); run.setText(text,0); key = ""; left = false; right = false; addUnderline(run, underline); }else{ if(left==true && right==false){ key += runText; run.setText("",0); addUnderline(run, underline); } if(left==false){ continue; } } } return StringUtils.isEmpty(params.get(key))?replace:getReplaceValue(params.get(key)); } /** * <br>描 述: 添加下划线 * <br>作 者: shizhenwei * <br>历 史: (版本) 作者 时间 注释 * @param run * @param underline * @return */ public static XWPFRun addUnderline(XWPFRun run,boolean underline){ //是否添加下划线 if(underline){ run.setUnderline(UnderlinePatterns.SINGLE); }else{ run.setUnderline(UnderlinePatterns.NONE); } return run; } }
package com.sicdt.sicsign.web.utils; import java.io.IOException; import java.io.InputStream; import java.util.Map; import org.apache.poi.xwpf.converter.core.XWPFConverterException; public class WordUtils { /** * <br> * 描 述: doc内容改变 <br> * 作 者: shizhenwei <br> * 历 史: (版本) 作者 时间 注释 * * @param is * doc文档模板 * @param params * key value 将模板里的可以替换为响应VALUE * @return * @throws IOException */ public static byte[] docContentChange(InputStream is, Map<String, String> params) throws IOException { return DocxUtils.docContentChange(is, params); } /** * <br> * 描 述: docx内容改变 <br> * 作 者: shizhenwei <br> * 历 史: (版本) 作者 时间 注释 * * @param is * docx文档模板 * @param params * key value 将模板里的可以替换为响应VALUE * @return * @throws IOException * @throws XWPFConverterException */ public static byte[] docxContentChange(InputStream is, Map<String, String> params) throws XWPFConverterException, IOException { return DocxUtils.docxContentChange(is, params); } /*** * <br> * 描 述: docx内容预览 <br> * 作 者: zhaowei <br> * 历 史: (版本) 作者 时间 注释 * * @param is * @param params * @return * @throws XWPFConverterException * @throws IOException */ public static byte[] docxContentChangeView(InputStream is, Map<String, String> params) throws XWPFConverterException, IOException { return DocxUtils.docxContentChange(is, params,DocxUtils.PREVIEW_REPLACE); } /*** * <br> * 描 述: docx内容预览 <br> * 作 者: zhaowei <br> * 历 史: (版本) 作者 时间 注释 * * @param is * @param params * @return * @throws XWPFConverterException * @throws IOException */ public static byte[] docxContentChangeDownload(InputStream is, Map<String, String> params) throws XWPFConverterException, IOException { return DocxUtils.docxContentChange(is, params,DocxUtils.DOWNLOAD_REPLACE); } /** * <br> * 描 述: 将docx字节数组流转换为pdf字节数组流 <br> * 作 者: shizhenwei <br> * 历 史: (版本) 作者 时间 注释 * * @param docxBytes * docx文档字节数组 * @return * @throws XWPFConverterException * @throws IOException * 注:需在部署系统安装word对应的中文字体 */ public static byte[] docx2pdf(byte[] docxBytes) throws XWPFConverterException, IOException { return DocxUtils.docx2pdf(docxBytes); } /** * <br> * 描 述: 将Word模板流改变内容后转换为pdf字节数组流 <br> * 作 者: shizhenwei <br> * 历 史: (版本) 作者 时间 注释 * * @param is * docx文档输入流 * @param params * key value 将模板里的可以替换为响应VALUE * @return * @throws IOException * @throws XWPFConverterException * * 注:需在部署系统安装word对应的中文字体 */ public static byte[] docx2pdf(InputStream is, Map<String, String> params) throws XWPFConverterException, IOException { return DocxUtils.docx2pdf(is, params,DocxUtils.NULL_REPLACE); } }
2.poi版本
<!-- 以下是POI相关使用 注:版本号不可轻易更改 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId> <version>1.0.6</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.17</version> </dependency>
3.模板样式