Java中經常使用到的文件操做那些事(一)——替換doc文檔模板,生成真實合同案例

  工做中,咱們時常會遇到一些操做文件的操做,好比在線生成合同模板,上傳/下載/解析Excel,doc文檔轉爲pdf等操做。本文就已工做中遇到的在線生成合同爲例,簡要地介紹一種文檔替換寫法。java

本文目的:給出源文件模板,經過程序操做後,替換模板中的指定內容,從而生成固定模板的文件。apache

使用場景:生成固定格式的合同信息。工具

原理:給一個文檔模板,須要替換的內容以 $$包含,而後,在代碼中給須要替換的字段賦值,生成新的文檔。spa

工具包:poi-ooxml-3.10.jar   本身網上下載調試

代碼:日誌

 1 package word2pdf;  2 
 3 import java.io.FileOutputStream;  4 import java.util.HashMap;  5 import java.util.Iterator;  6 import java.util.List;  7 import java.util.Map;  8 import java.util.Map.Entry;  9 import java.util.Set; 10 
11 import org.apache.poi.POIXMLDocument; 12 import org.apache.poi.xwpf.usermodel.XWPFDocument; 13 import org.apache.poi.xwpf.usermodel.XWPFParagraph; 14 import org.apache.poi.xwpf.usermodel.XWPFRun; 15 import org.apache.poi.xwpf.usermodel.XWPFTable; 16 import org.apache.poi.xwpf.usermodel.XWPFTableCell; 17 import org.apache.poi.xwpf.usermodel.XWPFTableRow; 18 
19 public class DocWriterTest { 20 
21     public static void searchAndReplace(String srcPath, String destPath, Map<String, String> map) { 22         try { 23             XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(srcPath)); 24             /**
25  * 替換段落中的指定文字 26              */
27             Iterator<XWPFParagraph> itPara = document.getParagraphsIterator(); 28             while (itPara.hasNext()) { 29                 XWPFParagraph paragraph = (XWPFParagraph) itPara.next(); 30                 Set<String> set = map.keySet(); 31                 Iterator<String> iterator = set.iterator(); 32                 while (iterator.hasNext()) { 33                     String key = iterator.next().trim(); 34                     List<XWPFRun> run = paragraph.getRuns(); 35                     int runSize = run.size(); 36                     for (int i = 0; i < runSize; i++) { 37                         String text = run.get(i).getText(0); 38                         System.out.println("++++++text++++++:" + text); 39                         for (Entry<String, String> e : map.entrySet()) { 40                             if (text != null && text.contains(e.getKey())) { 41                                 text = text.replace(e.getKey(), e.getValue()); 42                                 System.out.println("++++++text222222222++++++:" + text); 43                                 run.get(i).setText(text, 0); 44  } 45  } 46  } 47  } 48  } 49 
50             /**
51  * 替換表格中的指定文字 52              */
53             Iterator<XWPFTable> itTable = document.getTablesIterator(); 54             while (itTable.hasNext()) { 55                 XWPFTable table = (XWPFTable) itTable.next(); 56                 int count = table.getNumberOfRows(); 57                 for (int i = 0; i < count; i++) { 58                     XWPFTableRow row = table.getRow(i); 59                     List<XWPFTableCell> cells = row.getTableCells(); 60                     for (XWPFTableCell cell : cells) { 61                         for (XWPFParagraph p : cell.getParagraphs()) { 62                             for (XWPFRun r : p.getRuns()) { 63                                 String text = r.getText(0); 64                                 for (Entry<String, String> e : map.entrySet()) { 65                                     if (text != null && text.contains(e.getKey())) { 66                                         text = text.replace(e.getKey(), e.getValue()); 67                                         r.setText(text, 0); 68  } 69  } 70  } 71  } 72 
73  } 74  } 75  } 76             FileOutputStream outStream = null; 77             outStream = new FileOutputStream(destPath); 78  document.write(outStream); 79  outStream.close(); 80         } catch (Exception e) { 81  e.printStackTrace(); 82  } 83 
84  } 85 
86     public static void main(String[] args) throws Exception { 87         Map<String, String> map = new HashMap<String, String>(); 88         map.put("$name$", "coco"); 89         map.put("$sex$", "女"); 90         map.put("work", "Java開發"); 91         String srcPath = "E:\\cocoxu\\test_mode\\sourcefile.docx"; 92         String destPath = "E:\\cocoxu\\test_mode\\destfile.docx"; 93  searchAndReplace(srcPath, destPath, map); 94  } 95 }

調試時遇到的報錯:code

1.xml

java.lang.IllegalStateException: Zip File is closed
at org.apache.poi.openxml4j.util.ZipFileZipEntrySource.getEntries(ZipFileZipEntrySource.java:45)
at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:182)
at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:665)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:226)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:186)
at org.apache.poi.POIXMLDocument.openPackage(POIXMLDocument.java:67)
at word2pdf.DocWriterTest.searchAndReplace(DocWriterTest.java:23)
at word2pdf.DocWriterTest.main(DocWriterTest.java:93)blog

 

此類錯看似是zip文件被關閉,其實否則。實際上是因爲文檔路徑寫錯,找不到文件致使的。ip

String srcPath = "E:\\cocoxu\\\test_mode\\sourcefile.docx";

 

二、沒有生產想要的文件:

sourcefile.docx內容:

目的是用代碼中的內容,替換文檔中的內容,可是咱們第一次獲得的確實這樣的:

在代碼中打印日誌,能夠看到,word文檔中的$name$被跨行分開了:

原本是一行的東西,爲何代碼執行操做的時候會被分紅三行呢?這個就是doc文檔操做的問題啦 ,

 方法一:操做源文檔,對文檔中全部拼寫語法不合規範的都忽略

方法二:建立一個新文檔,在純英文格式下拼寫字段,而後複製帶源文件中,便可。

 

 最終獲得的目的問題內容:

 至此,咱們用java操做文檔的案例就結束了,實際工做中也能夠模仿此類代碼去生成哦。

相關文章
相關標籤/搜索