一、引入freemarker依赖
<!--word生成工具类-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.24-incubating</version>
</dependency>
二、准备好word模板和wordXML模板
1、word模板
2、word模板另存为xml格式
3、打开xml,先进行格式化,这样更好编辑
格式化好后,我们可以查找字段名,进行定位,找到name字段,所在的位置
刚开始是这样的,但是因为我们的用户表格,肯定不止一个用户,所以我们要修改好xml,添加list,如下:
设置图片的宽高,防止图片变形,或者图片太大超出word页面
改好xml后,我们将xml重命名,将后缀改为 ftl ,我这里是test.ftl
三、工具类
1、FileUtils
import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.ss.usermodel.Workbook;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
public class FileUtils extends org.apache.tomcat.util.http.fileupload.FileUtils {
/**
* 将图片内容转换成Base64编码的字符串,并获得图片宽高,进行缩放
* @param imageFile 图片文件的全路径名称
* @param flag 判断图片是否是用户头像
* @return base64字符串和图片宽高
*/
public static Map<String,String> getImageBase64String(String imageFile,boolean flag) {
Map<String,String> map = new HashMap<>();
if (StringUtils.isEmpty(imageFile)) {
return null;
}
File file = new File(imageFile);
if (!file.exists()) {
return null;
}
InputStream is = null;
InputStream is1 = null;
byte[] data = null;
try {
is = new FileInputStream(file);
is1 = new FileInputStream(file);
data = new byte[is.available()];
is.read(data);
//获取图片宽高
BufferedImage image = ImageIO.read(is1);
//图片的原始宽高
int height = image.getHeight();
int width = image.getWidth();
//如果图片是用户头像的话,按照50*50的标准来判断是否要缩小,否则的话按照500*500
if (flag){
//宽或高有一项大于50时,等比缩小
if (width > 50 || height > 50){
int cWidth = 50;
int cHeight = 50;
int showWidth = cWidth;
int showHeight = cHeight;
//原图宽高太大进行等比缩放
if(1.0 * width/height >= 1.0 * cWidth/cHeight){
//图片比较宽
showHeight = showWidth * height / width;
}else {
//图片比较长
showWidth = showHeight * width / height;
}
map.put("height",Integer.toString(showHeight));
map.put("width",Integer.toString(showWidth));
}else {
//否则使用图片的原始大小
map.put("height",Integer.toString(height));
map.put("width",Integer.toString(width));
}
}else {
//宽或高大于500时,进行缩放
if (width > 500 || height > 500){
int cWidth = 500;
int cHeight = 500;
int showWidth = cWidth;
int showHeight = cHeight;
//原图宽高太大进行等比缩放
if(1.0 * width/height >= 1.0 * cWidth/cHeight){
//图片比较宽
showHeight = showWidth * height / width;
}else {
//图片比较长
showWidth = showHeight * width / height;
}
map.put("height",Integer.toString(showHeight));
map.put("width",Integer.toString(showWidth));
}else {
map.put("height",Integer.toString(height));
map.put("width",Integer.toString(width));
}
}
is.close();
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
map.put("encode",encoder.encode(data));
return map;
}
}
2、WordUtils
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import java.io.*;
import java.util.Map;
public class WordUtils {
/**
* @param dataMap 导出数据
* @param templateName 要使用的模板的名称
* @param path 导出word的路径以及文件名称
* 通过模板导出word格式文件
* */
public void exportWord(Map<String,Object> dataMap,String templateName,String path) throws IOException, TemplateException {
//Configuration 用于读取ftl文件
Configuration configuration = new Configuration(new Version("2.3.0"));
configuration.setDefaultEncoding("utf-8");
//指定路径(根据某个类的相对路径指定)
configuration.setClassForTemplateLoading(this.getClass(),"/template");
//输出文档路径及名称
File outFile = new File(path);
//以utf-8的编码读取ftl文件
Template template = configuration.getTemplate(templateName, "utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);
template.process(dataMap, out);
out.close();
}
}
四、controller测试
@RestController
@EnableTransactionManagement
@RequestMapping("/test")
public class TestController{
@ResponseBody
@GetMapping("/exportWord")
public JSONObject exportWord(HttpServletResponse response){
try {
//这里是直接模拟数据,可以按照自己的实际需求更改
//需要导出的模板的数据
Map<String,Object> dataMap = new HashMap<>();
//用户列表
List<Map<String,Object>> userList = new ArrayList<>();
//第一个用户
Map<String,Object> user1 = new HashMap<>();
user1.put("name","admin");
user1.put("phone","12345678910");
user1.put("email","123@qq.com");
//用户头像,包括base64字符串、图片宽、图片高
user1.put("photo",FileUtils.getImageBase64String("E:\\document\\图片\\1.png",true));
userList.add(user1);
//第二个用户
Map<String,Object> user2 = new HashMap<>();
user2.put("name","藏剑");
user2.put("phone","13252101111");
user2.put("email","cj@163.com");
user2.put("photo",FileUtils.getImageBase64String("E:\\document\\图片\\2.png",true));
userList.add(user2);
//第三个用户
Map<String,Object> user3 = new HashMap<>();
user3.put("name","霸刀");
user3.put("phone","15244447777");
user3.put("email","bd@111.com");
user3.put("photo",FileUtils.getImageBase64String("E:\\document\\图片\\3.png",true));
userList.add(user3);
List<String> picList1 = new ArrayList<>();
picList1.add("E:\\document\\图片\\儒风.jpg");
picList1.add("E:\\document\\图片\\雪河.jpg");
List<String> picList2 = new ArrayList<>();
picList2.add("E:\\document\\图片\\风雷.jpg");
picList2.add("E:\\document\\图片\\驰冥.jpg");
picList2.add("E:\\document\\图片\\破虏.jpg");
//第一个图片list
List<Map<String,String>> pictureList1 = new ArrayList<>();
//第二个图片list
List<Map<String,String>> pictureList2 = new ArrayList<>();
for (String s : picList1) {
pictureList1.add(FileUtils.getImageBase64String(s,false));
}
for (String s : picList2) {
pictureList2.add(FileUtils.getImageBase64String(s,false));
}
//将处理好的数据,放到模板数据中
dataMap.put("pictureList1",pictureList1);
dataMap.put("pictureList2",pictureList2);
dataMap.put("userList",userList);
dataMap.put("code","TESTCODE001");
//获取当前项目根路径下的temp文件夹
String fullPath = System.getProperty("user.dir")+"/temp";
File file = new File(fullPath);
//将文件导出到temp文件夹下,并命名为test.doc
String wordName = file.getPath()+"/test.doc";
WordUtils wordUtils = new WordUtils();
wordUtils.exportWord(dataMap,"test.ftl",wordName);
} catch (IOException e) {
e.printStackTrace();
return failure("导出失败");
} catch (TemplateException e) {
e.printStackTrace();
return failure("导出失败");
}
return null;
}
}
五、效果
看下什么时候更新个,word模板转pdf的