前言
通過freemarker模板生成的word文檔實(shí)際上不是真正意義上的ms word標(biāo)準(zhǔn)文檔,它仍然是xml文件,而docx實(shí)際上是一個壓縮文件。所以使用以下方法對freemarker模板生成的word進(jìn)行優(yōu)化,保證生成的文件是真正意義上的ms word標(biāo)準(zhǔn)文檔。
解決方案
- 使用壓縮工具打開docx模板,取出document.xml,如下圖:
- 將用壓縮工具打開后的docx文檔里面的document.xml復(fù)制出來,并將document.xml后綴改為.ftl,然后進(jìn)行參數(shù)預(yù)設(shè)。
- 將內(nèi)容格式化后修改需要替換的內(nèi)容為freemarker標(biāo)簽,對document.ftl進(jìn)行參數(shù)預(yù)設(shè),如下圖:
- 文件準(zhǔn)備好后存放到某個目錄下,docx文件為將要生成好的docx文件樣式模版,必須要有的。如下圖:
- 程序代碼
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class Main {
public static void main(String[] args) {
//模版文件存放目錄
String templatepath = "E:/test/";
//模版樣式文件名
String docxname = "document.docx";
//模版xml文件
String xmlname = "document.xml";
//替換freemarker標(biāo)簽后的臨時(shí)xml文件
String tmpxmlpath = "E:/test/temp.xml";
//最終生成的docx文件
String targetpath = "E:/test/final.docx";
// 數(shù)據(jù)
Map<String,Object> data = new HashMap();
data.put("summary","這里是替換的文字");
// 生成文檔
try {
outputWord(templatepath, docxname, xmlname, tmpxmlpath, targetpath, data);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description 根據(jù)參數(shù)生成docx合同文檔
* @author HubertToLee
* @param templatepath 模板所在文件夾
* @param docxname docx格式模板文件名(不帶路徑)
* @param xmlname xml格式模板,有freemaker標(biāo)記(不帶路徑)
* @param tmpxmlpath 臨時(shí)xml文件路徑
* @param targetPath 目標(biāo)文件路徑
* @param param 待填充數(shù)據(jù)
* @return
* @throws Exception
*/
private static boolean outputWord(String templatepath, String docxname, String xmlname,
String tmpxmlpath, String targetPath, Map<String, Object> param) throws Exception {
//-------------start-----------------
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File(templatepath));
//以UTF-8的編碼格式讀入文件
Template template = cfg.getTemplate(xmlname,"UTF-8");
//以UTF-8的編碼格式輸出文件
template.setOutputEncoding("UTF-8");
Writer out = new FileWriter(new File(tmpxmlpath));
// 數(shù)據(jù)放到模板xml里面,生成帶數(shù)據(jù)的xml
template.process(param, out);
if (out != null) {
out.close();
}
//-------------end-----------------
//以上這塊代碼目的只為生替換freemarker標(biāo)簽后的xml文件
//實(shí)際開發(fā)中,也可以用替換后的字符串生成xml文件來生成word
File file = new File(tmpxmlpath);
File docxFile = new File(templatepath + "/" + docxname);
ZipFile zipFile = new ZipFile(docxFile);
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(targetPath));
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();
InputStream is = zipFile.getInputStream(next);
// 把輸入流的文件傳到輸出流中 如果是word/document.xml由我們輸入
zipout.putNextEntry(new ZipEntry(next.toString()));
if ("word/document.xml".equals(next.toString())) {
InputStream in = new FileInputStream(file);
while ((len = in.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
in.close();
} else {
while ((len = is.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
is.close();
}
}
zipout.close();
return true;
}
}
- 會在指定目錄下生成文件。如下圖:
文章來源地址http://www.zghlxwxcb.cn/news/detail-788395.html
文章來源:http://www.zghlxwxcb.cn/news/detail-788395.html
到了這里,關(guān)于freemarker模板生成的word文檔優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!