背景:周二下午业务部门提需求,胶东机场出口货物需要.jpg格式空运清单,挺急的。那就啥也别说了,会不会做的赶紧做吧,于是,周三下午做完测试OK,等业务部门下班后更新服务。周四上午做了份操作流程文档告诉业务部门可以用了,没过两个小时,就说改换Excel导出数据了,好家伙,直呼 好家伙 !也没啥事,就当锻炼自己了吧。在此记录一下这两天的成果,自己备份同时也分享一下。
经过查找资料,找到的可行方案如下:
将数据库查出来的数据,填充到freemarker模板中生成HTML文件,再将HTML文件转成.jpg图片,nice!
一顿操作猛如虎,步骤如下:
1.添加Maven依赖:
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
<dependency>
<groupId>com.github.xuwei-k</groupId>
<artifactId>html2image</artifactId>
<version>0.1.0</version>
</dependency>
<!-- freemarker模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.新增freemarker相关配置
spring.freemarker.cache = false
spring.freemarker.charset = UTF-8
spring.freemarker.check-template-location = true
spring.freemarker.expose-request-attributes = true
spring.freemarker.request-context-attribute = request
spring.freemarker.content-type = text/html
spring.freemarker.content-template-loader-path = classpath:/templates
或者:
spring:
freemarker:
cache: false
charset: UTF-8
check-template-location: true
expose-request-attributes: true
request-context-attribute: request
content-type: text/html
content-template-loader-path: classpath:/templates
以上为不同的两种形式,作用相同,根据自己代码类型使用。
3.定义模板文件declare.ftl,路径为/templates下面。
<html>
<head>
<style>
</style>
</head>
<body>
<h4 style="text-align:center;">
<span >主单号:${model[0].billNo!""}</span>
</h4>
<p>
<table style="width:100%;margin-top:5px;" cellpadding="2" cellspacing="0" border="1" bordercolor="#000000">
<tbody>
<tr>
<td style="text-align:center;">编号</td>
<td style="text-align:center;">分运单号</td>
<td style="text-align:center;">件数</td>
<td style="text-align:center;">币制代码</td>
<td style="text-align:center;">订单毛重</td>
<td style="text-align:center;">商品名称</td>
<td style="text-align:center;">HS编码</td>
<td style="text-align:center;">数量</td>
<td style="text-align:center;">金额</td>
</tr>
<#if model?? && model?size gt 0>
<#list model as item>
<tr>
<td style="text-align:center;">${item_index+1}</td>
<td style="text-align:center;">${item.logisticsNo!""}</td>
<td style="text-align:center;">${item.piecesNum!""}</td>
<td style="text-align:center;">${item.currCode!""}</td>
<td style="text-align:center;">${item.weight!""}</td>
<td style="text-align:center;">${item.goodsName!""}</td>
<td style="text-align:center;">${item.hsCode!""}</td>
<td style="text-align:center;">${item.number!""}</td>
<td style="text-align:center;">${item.worth!""}</td>
</tr>
</#list>
</#if>
</tbody>
</table>
<br />
</p>
</body>
</html>
4.创建FreemarkeTools工具类,用于数据转HTML、HTML转图片
package com.cg.oms.core.utils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.Map;
/**
*
*/
public class FreemarkeTools {
/**
* 获取模板转为html
*/
public static String ftlToString(Map<String,Object> map, String templateName) throws IOException, TemplateException {
String value = "";
Configuration configuration = new Configuration();
Resource resource = new ClassPathResource("templates");
File sourceFile = resource.getFile();
String ftlPath = sourceFile.getAbsolutePath();
String filName = templateName;
String encoding = "UTF-8";
StringWriter out = new StringWriter();
configuration.setDirectoryForTemplateLoading(new File(ftlPath));
Template template = configuration.getTemplate(filName,encoding);
template.setEncoding(encoding);
template.process(map, out);
out.flush();
out.close();
value = out.getBuffer().toString();
return value;
}
/**
* html转为图片
* @param html
* @param inputFileName
* @param outputFileName
* @param widthImage
* @param heightImage
* @return
* @throws IOException
*/
public static String turnImage(String html, String inputFileName, String outputFileName
,int widthImage, int heightImage) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(inputFileName),"UTF-8"));
bufferedWriter.write(html);
bufferedWriter.newLine();
bufferedWriter.flush();
bufferedWriter.close();
File f = new File(inputFileName);
Java2DRenderer renderer = new Java2DRenderer(f, widthImage, heightImage);
BufferedImage image = renderer.getImage();
FSImageWriter imageWriter = new FSImageWriter();
imageWriter.setWriteCompressionQuality(0.9f);
File imgFile = new File(outputFileName);
FileOutputStream fout = new FileOutputStream(imgFile);
imageWriter.write(image, fout);
fout.close();
return outputFileName;
}
}
5.Controller接口:
@Controller
public class BatchController extends BaseController {
@Autowired
ProjectConfig projectConfig;
@Autowired
private CyyBillService cyyBillService;
@Autowired
private ChPictureFileService chPictureFileService;
/**
* 生成图片
*/
@RequestMapping("/batch/exportPicture")
@ResponseBody
@RepeatSubmit
public Dict exportPicture(HttpServletResponse response, @RequestParam String billNo) throws Exception {
ModelMap modelMap = new ModelMap();
List<DeclareDetailDTO> details = new ArrayList<>();
// 根据billNo查询提单信息
details = cyyBillService.exportPicture(billNo);
Integer height = 100;
height += details.size() * 26;
if (height < 800 ){
height = 800;
}
modelMap.put("model", details);
String templateName = "declare.ftl";
String picturePath = "D:/oms/download/downloadPicture/";
String html = FreemarkeTools.ftlToString(modelMap, templateName);
String htmlFilePath = picturePath+billNo+".html";
String imageFilePath = picturePath+billNo+".jpg";
String imgPath = FreemarkeTools.turnImage(html,htmlFilePath,imageFilePath,1000,height);
System.out.println("文件生成路径" + imgPath);
CgAdmin user = ShiroUtils.getSysUser();
System.out.printf("ID "+user.getId());
// chPictureFileService.save(billNo, htmlFilePath, user.getId(),0); //保存HTML文件信息
// chPictureFileService.save(billNo, imageFilePath, user.getId(),1); //保存图片信息
return Success();
}
/**
* 下载图片
*/
@RequestMapping("/batch/downloadPicture")
@ResponseBody
@RepeatSubmit
public void downloadPicture(HttpServletResponse response, @RequestParam String billNo) throws Exception {
// 查询此提单号下的图片信息
ChPictureFile chPictureFile = chPictureFileService.selectPictureByBillNo(billNo);
File file ;
if (null == chPictureFile){
// 图片信息为空,输出error图片
ClassPathResource classPathResource = new ClassPathResource("static/download/error.jpg");
String resource = classPathResource.getURL().getPath();
file = new File(resource);
billNo = "error";
} else {
// 文件地址
file = new File(chPictureFile.getPath());
}
// 传入输出对象
FileInputStream fileInputStream = new FileInputStream(file);
// 设置相关格式
response.setContentType("application/force-download");
// 设置下载后的文件名以及header
response.addHeader("Content-disposition", "attachment;fileName=" + billNo+".jpg");
// 创建输出对象
ServletOutputStream outputStream = response.getOutputStream();
// 常规操作
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fileInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
fileInputStream.close();
}
}
输出效果图:
关于以上,有疑问欢迎留言,大家互相交流学习,更欢迎大牛指正!