poi
java2word
freemarker
最后选用freemarker,为什么呢?业务需要。
生成doc格式,比较简单,这里就不列举了,网上有大量的例子
生成思路大概就是保存一个doc文件,改后缀位xml,占位符去渲染。其中图片转换成base64格式。
这里主要讲docx格式。测试环境office 2013 2016
特殊符号需要转义,否则报错
docx格式本质上是个zip压缩包。
- 新建docx文件,插入自己需要的格式,如图
- 修改后缀为zip
[Content_Types].xml
如果需要插图,需要修改此文件,这里以jpg图片为例,
插入图片word转为jpeg,建议图片修改jpg为jepg
如果插入其他格式在此文件夹添加对应的说明
3.打开word文件夹,主要改动也是在这里
注意: <pic:cNvPr id=“1” name=“图片 1”/> 中的id最好使用数字,前面使用的字符串出现打开文件弹错误的情况
=====================================================================
干货来了
目录结构
springboot maven引入freemarker
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
freemarker相关配置
application.yml
这里就不啰嗦了
spring:
freemarker:
charset: UTF-8
suffix: .html
template-loader-path: /templates
content-type: text/html; charset=utf-8
java 工具类
import java.io.*;
import java.util.Date;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateNotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* @Description: word工具类
* @Auther: simp
* @Date: 2020/11/27 11:18
* @Version: 1.0
*/
@Slf4j
@Component
public class WordUtils {
private static final String path = "/project/upload/doc/";
public static Configuration getConfiguration() {
Configuration config = new Configuration(Configuration.VERSION_2_3_28);
config.setDefaultEncoding("utf-8");
config.setClassForTemplateLoading(WordUtils.class, "/templates");
config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
return config;
}
/**
* FreeMarker生成Word
* @param dataMap 数据
* @param templateName 目标名
*/
public static ByteArrayInputStream createXml(JSONObject dataMap, String templateName) {
Template template = null;
ByteArrayInputStream in = null;
if(templateName.endsWith(".html")) {
templateName = templateName.substring(0, templateName.indexOf(".html"));
}
try {
template = getConfiguration().getTemplate(templateName + ".html");
} catch (TemplateNotFoundException e) {
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
StringWriter out = new StringWriter();
try {
template.process(dataMap, out);
in = new ByteArrayInputStream(out.toString().getBytes("utf-8"));//这里一定要设置utf-8编码 否则导出的word中中文会是乱码
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return in;
}
public static String exportWord(String report) {
JSONObject jsonObject = JSONObject.parseObject(report);
Date date = new Date(Long.parseLong(jsonObject.getString("time")));
String docName = new StringBuffer()
.append(DateUtil.format(date, "yyyyMMddHHmmss"))
.append("_")
.append(jsonObject.getString("taskName"))
.append(".docx").toString();
String saveFilePath = path + docName;
String time = DateUtil.format(date, "yyyy/MM/dd HH:mm:ss");
jsonObject.put("time", time);
JSONArray stepInfos = jsonObject.getJSONArray("stepInfos");
JSONArray images = new JSONArray();
int count = 10;
for (Object item : stepInfos) {
JSONObject step = (JSONObject) item;
if (step.containsKey("images")) {
JSONArray list = step.getJSONArray("images");
for (Object it : list) {
JSONObject image = (JSONObject) it;
if (image.containsKey("path")) {
image.put("id", count);
image.put("embed", "rId" + count);
image.put("name", "图片 " + count);
String path = image.getString("path");
String ext = path.substring(path.lastIndexOf("."));
ext = ".jpg".equals(ext) ? ".jpeg" : ext;
JSONObject imageJson = new JSONObject();
imageJson.put("embed", image.getString("embed"));
imageJson.put("id", image.getString("id"));
imageJson.put("ext", ext);
imageJson.put("name", "image" + count + ext);
try {
FileInputStream fileIn = new FileInputStream(image.getString("path"));
imageJson.put("code", fileIn);
} catch (Exception e) {
}
images.add(imageJson);