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


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

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

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

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

工具包: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 }

調試時遇到的報錯:

1.

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)

 

此類錯看似是zip文件被關閉,其實不然。其實是由於文檔路徑寫錯,找不到文件導致的。

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

 

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

sourcefile.docx內容:

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

在代碼中打印日志,可以看到,word文檔中的$name$被跨行分開了:

本來是一行的東西,為什么代碼執行操作的時候會被分成三行呢?這個就是doc文檔操作的問題啦 ,

 方法一:操作源文檔,對文檔中所有拼寫語法不合規范的都忽略

方法二:創建一個新文檔,在純英文格式下拼寫字段,然后復制帶源文件中,即可。

 

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

 至此,我們用java操作文檔的案例就結束了,實際工作中也可以模仿此類代碼去生成哦。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM