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.模板樣式