Java通过FreeMarker生成docx word文档
public static void main(String[] args) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("title","放肆-Vae");
data.put("content","你的放肆烧燃起怒火,我的放肆如大雨滂沱;你的放肆掀风起云涌,我的放肆平沧海澜波。");
GenerateDocxUtil.freemarkerDocxTest("/Users/weichenxu/Downloads/worddocx/temp/",data,"/Users/weichenxu/Downloads/worddocx/file/放肆.docx");
}
public class GenerateDocxUtil {
private static Logger logger = LoggerFactory.getLogger(GenerateDocxUtil.class);
public static void freemarkerDocxTest(String rootPath, Map<String,Object> dataMap, String docxPath) throws Exception{
//配置freemarker模板
Configuration configuration = new Configuration();
String fileDirectory = rootPath;
configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
String temName = "tem1.xml";
String docxZipPath = rootPath + "tem1.zip";
Template template = configuration.getTemplate(temName);
//通过模板生成的xml临时文件 方法结束后删除该临时文件
String outFilePath = rootPath + UUID.randomUUID().toString().replace("-","") + ".xml";
//指定输出word xml文件的路径
File docXmlFile = new File(outFilePath);
FileOutputStream fos = new FileOutputStream(docXmlFile);
Writer out = new BufferedWriter(new OutputStreamWriter(fos),10240);
template.process(dataMap,out);
if(out != null){
out.close();
}
//以下代码 主要用来加密已经生成的xml文件,把xml文件正式转换成加密的word文档
//包装输入流
ZipInputStream zipInputStream = wrapZipInputStream(new FileInputStream(new File(docxZipPath)));
//包装输出流
ZipOutputStream zipOutputStream = wrapZipOutputStream(new FileOutputStream(new File(docxPath)));
//正式加密替换成docx格式文档
List<String> itemNameList = new ArrayList<>();
itemNameList.add("word/document.xml");
//如果需要替换图片添加此行代码,"word/media/image1.png"为解压出来docx模板后,模板中对应图片的完整路径及名称,如果你添加的图片为jpg格式,那么图片名称会是"image1.jpg"或"image1.jpeg",各位自己视情况修改,如需替换多张图片就举一反三,往list插入多个元素,我相信你们可以理解的
itemNameList.add("word/media/image1.png");
List<InputStream> itemInputStreamList = new ArrayList<>();
itemInputStreamList.add(new FileInputStream(new File(outFilePath)));
//这里添加你想替换的图片
itemInputStreamList.add(new FileInputStream(new File(${图片路径})));
replaceItemList(zipInputStream, zipOutputStream, itemNameList, itemInputStreamList);
new File(outFilePath).delete();
logger.info("Word-docx文档生成完成");
}
public static ZipInputStream wrapZipInputStream(InputStream inputStream){
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
return zipInputStream;
}
public static ZipOutputStream wrapZipOutputStream(OutputStream outputStream){
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
return zipOutputStream;
}
public static void replaceItemList(ZipInputStream zipInputStream, ZipOutputStream zipOutputStream, List<String> itemNameList, List<InputStream> itemInputStreamList){
if(null == zipInputStream){return;}
if(null == zipOutputStream){return;}
ZipEntry entryIn;
try {
while((entryIn = zipInputStream.getNextEntry())!=null){
String entryName = entryIn.getName();
ZipEntry entryOut = new ZipEntry(entryName);
zipOutputStream.putNextEntry(entryOut);
byte [] buf = new byte[8*1024];
int len;
if(itemNameList.indexOf(entryName) != -1){
// 使用替换流
while((len = (itemInputStreamList.get(itemNameList.indexOf(entryName)).read(buf))) > 0) {
zipOutputStream.write(buf, 0, len);
}
} else {
// 输出普通Zip流
while((len = (zipInputStream.read(buf))) > 0) {
zipOutputStream.write(buf, 0, len);
}
}
// 关闭此 entry
zipOutputStream.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//e.printStackTrace();
for (InputStream itemInputStream:itemInputStreamList) {
close(itemInputStream);
}
close(zipInputStream);
close(zipOutputStream);
}
}
private static void close(InputStream inputStream){
if (null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void close(OutputStream outputStream){
if (null != outputStream){
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
License:
CC BY 4.0