场景:公司要求要更改word中的图片上的文字系数,动态生成文字效果图,并替换文字模板
如下图是需要我们将系数动态替换上的
左边是模板,右边是实现效果图
由于第一次学习使用freeMaker没有经验,看着觉得很难。
我采取的第一套方案是:图片上加水印的方式替换图片上的文字
弊端:图片加水印没办法处理竖型的文字,只能水平替换,那么侧边无法竖着替换
结果:not pass
方案二:采用POI的方式
弊端:POI只能实现word中普通文字替换,对于文本框替换实现不了,我是在word中图片上插入文本框进行替换的,故此方法不可行
结果: not pass
方案三:采用freeMaker
结果:可行
注意要点:
1、转换后的文件是doc类型的,如果转pdf需要采用doc转pdf的工具类实现
2、注意调整ftl模板的格式
下面我将重点讲讲方案三
第一步:引入jar包
<!-- 导出word文档 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
第二步:
1、因为有些需求,需要把word文档里面的特定数据,设置成可变的;所以需要某种方式,把可变量用标签(如${变量名})替换,通过后端赋值此变量名,重新生成的Word就能根据后端设置的内容变化。
2、替换方法:准备一份word模板文档,如:word_mode.doc(或 word_mode.docx) 文件,把可变内容,用标签${变量名}替换(如图1姓名:${name})
3、转成可读模板:全部设置完变量标签后,对此word文档进行另存为xml格式的文档(图2),保存后的文件名:word_mode.xml(即用户信息.xml)。再通过修改后缀名,最终生成模板(用于替换标签的):word_mode.ftl
import com.xiolift.ce.ceModules.Util.CommonUtils;
import com.xiolift.ce.ceModules.Util.OssUtil;
import com.xiolift.ce.ceModules.entity.body.req.HoistwayPlanBody;
import com.xiolift.ce.ceModules.entity.body.req.ShaftElevationBody;
import com.xiolift.ce.ceModules.service.WeChatPicService;
import com.xiolift.ce.common.util.RtMsg;
import com.xiolift.ce.common.util.SendMailUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.icepdf.core.pobjects.Document;
import org.icepdf.core.util.GraphicsRenderingHints;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@Service
@Slf4j
public class WeChatPicServiceImpl implements WeChatPicService {
/**
* 设置使用的编码格式
*/
private static final String CHARSET = "UTF-8";
/**
* 设置使用的版本
*/
private static final String VERSION = "2.3.0";
@Autowired
private OssUtil ossUtil;
/**
* 设置使用的编码格式
*/
private static final String CHARSET = "UTF-8";
/**
* 设置使用的版本
*/
private static final String VERSION = "2.3.0";
@Autowired
private OssUtil ossUtil;
/**
* 生成土建平面模板
*/
@SneakyThrows
@Override
public String createHoistwayModel(HoistwayPlanBody hoistwayPlanBody,String wordModePath,String wordModeFile) {
String filePath = "";
try {
// 1. 获取替换参数
Map<String, Object> wordData = initHoistwayWordMap(hoistwayPlanBody);
// 2. 设置配置内容
// 设置版本
Configuration configuration = new Configuration(new Version(VERSION));
// 指定加载Word模板的路径
configuration.setDirectoryForTemplateLoading(new File(wordModePath));
// 以UTF-8的编码格式,读取模板文档
Template template = configuration.getTemplate(wordModeFile, CHARSET);
// 3. 输出文档路径及名称
filePath = wordModePath + CommonUtils.generNumCode(6) +"-井道平面效果图.doc";
File outFile = new File(filePath);
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), CHARSET), 10240);
// 输出
template.process(wordData, writer);
writer.flush();
writer.close();
System.out.println("土建平面生成图导出已完成");
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
/**
* 平面图初始化数据
* @param hoistwayPlanBody
* @return
*/
private static Map<String, Object> initHoistwayWordMap(HoistwayPlanBody hoistwayPlanBody) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("pureOpenDoor", hoistwayPlanBody.getPureOpenDoor());
params.put("doorWidth", hoistwayPlanBody.getDoorWidth());
params.put("pureLiftCarWidth", hoistwayPlanBody.getPureLiftCarWidth());
params.put("pureHoistwayWidth",hoistwayPlanBody.getPureHoistwayWidth());
params.put("hwThick", hoistwayPlanBody.getHoistwayThick());
params.put("shaftDepth", hoistwayPlanBody.getShaftDepth());
params.put("pureLiftCarDepth", hoistwayPlanBody.getPureLiftCarDepth());
return params;
}
}
效果图如下: