1. 程式人生 > >如何向word文件寫入資料

如何向word文件寫入資料

大致流程:

1.建立模板docx並取出document.xml

新建一個docx文件,放在D盤命名test_template.docx

2.用winrar開啟test_template.docx,取出word/document.xml

把xml檔案格式化一下看起來更清晰,並且把要替換的內容用freemarker的指令代替,最後將檔案重新命名為test.xml放在D盤下面

3.準備工作完畢,上程式碼了,這個類是把內容填充到xml

  1. import java.io.File;  
  2. import java.io.IOException;  
  3. import java.io.Writer;  
  4. import java.util.Map;  
  5. import freemarker.template.Configuration;  
  6. import freemarker.template.Template;  
  7. import freemarker.template.TemplateException;  
  8. public class XmlToExcel {  
  9.     private static XmlToExcel tplm = null;  
  10.     private Configuration cfg = null;  
  11.     private XmlToExcel() {  
  12.         cfg = new Configuration();  
  13.         try {  
  14.             // 註冊tmlplate的load路徑  
  15.             // cfg.setClassForTemplateLoading(this.getClass(), "/template/");  
  16.             cfg.setDirectoryForTemplateLoading(new File("D:/"));  
  17.         } catch (Exception e) {  
  18.         }  
  19.     }  
  20.     private
     static Template getTemplate(String name) throws IOException {  
  21.         if (tplm == null) {  
  22.             tplm = new XmlToExcel();  
  23.         }  
  24.         return tplm.cfg.getTemplate(name);  
  25.     }  
  26.     /** 
  27.      *  
  28.      * @param templatefile 模板檔案 
  29.      * @param param 需要填充的內容 
  30.      * @param out 填充完成輸出的檔案 
  31.      * @throws IOException 
  32.      * @throws TemplateException 
  33.      */  
  34.     public static void process(String templatefile, Map param, Writer out) throws IOException, TemplateException {  
  35.         // 獲取模板  
  36.         Template template = XmlToExcel.getTemplate(templatefile);  
  37.         template.setOutputEncoding("UTF-8");  
  38.         // 合併資料  
  39.         template.process(param, out);  
  40.         if (out != null) {  
  41.             out.close();  
  42.         }  
  43.     }  
  44. }  

4.這個類是把填充完畢的xml轉成docx

  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.util.Enumeration;  
  7. import java.util.zip.ZipEntry;  
  8. import java.util.zip.ZipException;  
  9. import java.util.zip.ZipFile;  
  10. import java.util.zip.ZipOutputStream;  
  11. /** 
  12.  * 其實docx屬於zip的一種,這裡只需要操作word/document.xml中的資料,其他的資料不用動 
  13.  *  
  14.  * @author yigehui 
  15.  *  
  16.  */  
  17. public class XmlToDocx {  
  18.     /** 
  19.      *  
  20.      * @param documentFile 動態生成資料的docunment.xml檔案 
  21.      * @param docxTemplate docx的模板 
  22.      * @param toFileName 需要匯出的檔案路徑 
  23.      * @throws ZipException 
  24.      * @throws IOException 
  25.      */  
  26.     public void outDocx(File documentFile, String docxTemplate, String toFilePath) throws ZipException, IOException {  
  27.         try {  
  28.             File docxFile = new File(docxTemplate);  
  29.             ZipFile zipFile = new ZipFile(docxFile);  
  30.             Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();  
  31.             ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));  
  32.             int len = -1;  
  33.             byte[] buffer = new byte[1024];  
  34.             while (zipEntrys.hasMoreElements()) {  
  35.                 ZipEntry next = zipEntrys.nextElement();  
  36.                 InputStream is = zipFile.getInputStream(next);  
  37.                 // 把輸入流的檔案傳到輸出流中 如果是word/document.xml由我們輸入  
  38.                 zipout.putNextEntry(new ZipEntry(next.toString()));  
  39.                 if ("word/document.xml".equals(next.toString())) {  
  40.                     InputStream in = new FileInputStream(documentFile);  
  41.                     while ((len = in.read(buffer)) != -1) {  
  42.                         zipout.write(buffer, 0, len);  
  43.                     }  
  44.                     in.close();  
  45.                 } else {  
  46.                     while ((len = is.read(buffer)) != -1) {  
  47.                         zipout.write(buffer, 0, len);  
  48.                     }  
  49.                     is.close();  
  50.                 }  
  51.             }  
  52.             zipout.close();  
  53.         } catch (Exception e) {  
  54.             e.printStackTrace();  
  55.         }  
  56.     }  
  57. }  

5.main方法呼叫

  1. public static void main(String[] args) throws IOException, TemplateException {  
  2.         try {  
  3.             // xml的檔名  
  4.             String xmlTemplate = "test.xml";  
  5.             // docx的路徑和檔名  
  6.             String docxTemplate = "d:\\test_template.docx";  
  7.             // 填充完資料的臨時xml  
  8.             String xmlTemp = "d:\\temp.xml";  
  9.             // 目標檔名  
  10.             String toFilePath = "d:\\test.docx";  
  11.             Writer w = new FileWriter(new File(xmlTemp));  
  12.             // 1.需要動態傳入的資料  
  13.             Map<String, Object> p = new HashMap<String, Object>();  
  14.             List<String> students = new ArrayList<String>();  
  15.             students.add("張三");  
  16.             students.add("李四");  
  17.             students.add("王二");  
  18.             p.put("ddeptdept""研發部門");  
  19.             p.put("ddatedate""2016-12-15");  
  20.             p.put("dnamename", students);  
  21.             // 2.把map中的資料動態由freemarker傳給xml  
  22.             XmlToExcel.process(xmlTemplate, p, w);  
  23.             // 3.把填充完成的xml寫入到docx中  
  24.             XmlToDocx xtd = new XmlToDocx();  
  25.             xtd.outDocx(new File(xmlTemp), docxTemplate, toFilePath);  
  26.         } catch (Exception e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.     }