1、打开world模板,在需要填入的地方写入占位符:
PS:占位符格式"${占位符名称}",需事先规定好填充数据的字体样式及大小,需要加入图片的地方直接放入一张图片
3、 将存的.xml文件重命名为.ftl后缀,例中重命名后为:entryform.ftl
4、用编辑器打开.ftl文件,因为在将world文档转换为.xml文件时,会使我们之前设置好的占位符位置隔开,所以这里我们需要将占位符中间隔的代码全部删除,保持占位符格式
5、替换图片占位符:
找到图片的64位编码
6、保存退出,模板制作完成
2、映入worldutils工具类:
package com.zpw.back.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
/**
* @author Hu Wentao
* @date 2020/4/6-12:13
*/
@Component
public class WordUtil {
/**
* 生成word文件
* @param dataMap word中需要展示的动态数据,用map集合来保存
* @param templateName word模板名称,例如:test.ftl
* @param filePath 文件生成的目标路径,例如:D:/wordFile/
* @param fileName 生成的文件名称,例如:test.doc
*/
public static void createWord(Map dataMap,String templateName,String filePath,String fileName){
try {
//创建配置实例
Configuration configuration = new Configuration();
//设置编码
configuration.setDefaultEncoding("UTF-8");
//ftl模板文件
configuration.setClassForTemplateLoading(WordUtil.class,"/");
//获取模板
Template template = configuration.getTemplate(templateName);
//输出文件
File outFile = new File(filePath+File.separator+fileName);
//如果输出目标文件夹不存在,则创建
if (!outFile.getParentFile().exists()){
outFile.getParentFile().mkdirs();
}
//将模板和数据模型合并生成文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
//生成文件
template.process(dataMap, out);
//关闭流
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取文件里的图片
public String getImageStr(String imgFile) {
InputStream in = null;
byte[] data = null;
try {
if(imgFile.startsWith("http")){ //获取在线图片
URL url = new URL(imgFile);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20 * 1000);
in = conn.getInputStream();
}else{ //获取线下图片
in = new FileInputStream(imgFile);
}
//使用此种方式在获取在线图片时下载word中图片可能显示不全,其原因就是网络通讯往往是间断性的,一串字节往往分几批进行发送。本地程序调用available()方法有时得到0,这可能是对方还没有响应,也可能是对方已经响 应了,但是数据还没有送达本地。对方发送了1000个字节给你,也许分成3批到达,这你就要调用3次available()方法才能将数据总数全部得到。
/*int count = 0;
while (count == 0) {
count = in.available();
}
data = new byte[count];*/
int c;
ByteArrayOutputStream buff = new ByteArrayOutputStream();
while((c = in.read()) >= 0){
buff.write(c);
}
data = buff.toByteArray();
buff.close();
in.read(data);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
if(data!=null && data.length>0){
return encoder.encode(data);
}
return null;
}
}
3、封装填充数据:
PS:这里需要注意的两点:第一,日期格式应该做转换;第二,图片的填充略有不同
//生成报名表,存放于服务器中
//用于组装word页面需要的数据
Map dataMap = new HashMap();
//转换时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//和前端约定部门传部门id,这里通过部门id查出部门名称
Department department = departmentService.findById(employee.getDepartmentId());
/** 组装数据 */
dataMap.put("id", employee.getId());
dataMap.put("picture", wordUtil.getImageStr(employee.getPicture()));
dataMap.put("departmentId", department.getName());
dataMap.put("name", employee.getName());
dataMap.put("sex", employee.getSex());
dataMap.put("birthday", simpleDateFormat.format(employee.getBirthday()));
dataMap.put("political_landscape", employee.getPolitical_landscape());
dataMap.put("national", employee.getNational());
dataMap.put("marriage", employee.getMarriage());
dataMap.put("native_place", employee.getNative_place());
dataMap.put("qualifications", employee.getQualifications());
dataMap.put("professional_and_technical_titles", employee.getProfessional_and_technical_titles());
dataMap.put("first_academic", employee.getFirst_academic());
dataMap.put("first_degree", employee.getFirst_degree());
dataMap.put("first_academic_major", employee.getFirst_academic_major());
dataMap.put("first_academic_graduatedschool", employee.getFirst_academic_graduatedschool());
dataMap.put("first_academic_graduatedtime", employee.getFirst_academic_graduatedtime());
dataMap.put("highest_academic", employee.getHighest_academic());
dataMap.put("highest_degree", employee.getHighest_degree());
dataMap.put("highest_academic_major", employee.getHighest_academic_major());
dataMap.put("highest_academic_graduatedschool", employee.getHighest_academic_graduatedschool());
dataMap.put("highest_academic_graduatedtime", employee.getHighest_academic_graduatedtime());
dataMap.put("address", employee.getAddress());
dataMap.put("zip_code", employee.getZip_code());
dataMap.put("phone", employee.getPhone());
dataMap.put("email", employee.getEmail());
dataMap.put("resume", employee.getResume());
4、代码中调用:
/**
* 第一个参数:封装的占位符数据,类型:Map
* 第二个参数:模板位置
* 第三个参数:生成的文件的存放路径
* 第四个参数:生成world的文件名
* /
wordUtil.createWord(dataMap, "templates/entryform.ftl", uploadHead+entryFormFilesPath, fileOnlyName);