背景:
部门C++项目有导出Word报表的功能,用C++实现较复杂,刚好之前我在B端做过一版,领导让我用java协助下。为了让C++调用方便有想过使用.class文件,我将ftl模板文件放在本地位置,但是模板文件一直加载不到。无奈只好新建一个maven项目,将模板放在resource下。
一、依赖导入
1.1、新建maven项目
1.2、导入依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
需要在pom文件指定主方法,不然启动jar包的时候找不到主方法。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<!--指定main方法-->
<mainClass>com.hr.service.impl.GenerateWordService</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
二、模板制作
思路:编辑好一个Word文档,将Word另存为xml,修改后缀名为ftl
修改成英文名称,后缀名改为ftl
三、编码
在resources目录下新建static/wordtemplate文件夹,将模板文件拷贝进来,使用IDEA的Ctrl+Alt+L将内容格式化;这时候发现Word里保存的图片实际上是base64的字符串,只要将图片转换成base64的字符串并将模板内容替换就可以将图片写入Word文档中。至于别的字符串和循环列表之后需要参考ftl语法即可。ftl语法参考
生成文档的方法
public static void generateWord(Map<String, String> tempMap) {
Configuration configuration = new Configuration();
String fileName = "简历测试.docx";
String filPath = "H:\\报告生成" + File.separator + fileName;
File file = new File(filPath);
configuration.setClassForTemplateLoading(GenerateWordService.class, "/static/wordtemplate");
Template template = null;
Writer writer = null;
try {
template = configuration.getTemplate("test.ftl");
writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
template.process(tempMap, writer);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
图片转成base64字符串的方法
public static String imageToBase64Str(String imgFile) {
InputStream inputStream = null;
byte[] data = null;
try {
inputStream = new FileInputStream(imgFile);
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 加密
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
主方法
public static void main(String[] args) {
//获取传入的参数
String name = System.getProperty("name");
// System.out.println("传入的参数:" + name);
Map<String, String> map = new HashMap<>();
map.put("name", name);
map.put("agent", "男");
//加工图片
String base64Image = imageToBase64Str("H:\\image\\电子照一寸白底.jpg");
map.put("image", base64Image);
map.put("nation", "汉");
map.put("phone", "189*****205");
map.put("politicalStatus", "中共党员");
map.put("address", "河南省**县");
map.put("school", "***学院");
map.put("schoolName", "**县**乡**小学");
map.put("schoolAddress", "**县**乡**村");
generateWord(map);
}
四、测试
C++开发工程师可以查询C++ 调用jar包的代码,执行以下启动命令即可
执行jar包的命令
java -Dname=chenyicheng -Dfile.encoding=utf-8 -jar agent_word-1.0-SNAPSHOT.jar
名称 | 含义 |
---|---|
-Dname | 给java内的name属性赋值 |
-Dfile.encoding | 指定编码格式要不然报告有中文乱码 |