需求:
在开发的业务系统中我希望能有一个转出PDF功能。比如:转出订单,转出发货单等。
使用itext 与flying-pdf 对 thymeleaf 模板填充后生成PDF
1.准备中文字体,用于PDF中关于中文文字的显示。
链接: https://pan.baidu.com/s/1ubf9eWYHgqNgvtk0w7mauw 提取码: qd1i
存放位置
2.Maven 主要依赖
com.lowagie itext ${itext.version} org.apache.poi poi 3.9 org.apache.poi poi-ooxml 3.9 org.xhtmlrenderer flying-saucer-pdf 9.1.9
3.工具类
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.xml.xmp.XmpWriter;
import lombok.extern.slf4j.Slf4j;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.List;
import java.util.Map;
/**
* pdf处理工具类
*
*/
@Slf4j
public class PdfUtil {
/**
* 以文件流形式下载到浏览器
*
* @param templateEngine 配置
* @param templateName 模板名称
* @param listVars 模板参数集
* @param response HttpServletResponse
* @param fileName 下载文件名称
*/
public static void download(TemplateEngine templateEngine, String templateName, List
4.控制层方法 (原理是把对象传过去,由thymeleaf解析)
import com.flo.po.Dto.OrderDetailedDto;
import com.flo.po.Dto.OrderDto;
import com.flo.service.OrderDetailedService;
import com.flo.service.OrderService;
import com.flo.util.PdfUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.TemplateEngine;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 文档预览、下载
*
*/
@RestController
@RequestMapping(value = "/document")
@Api(tags = "文档预览、下载API")
public class DocumentController {
@Autowired
private TemplateEngine templateEngine;
@Autowired
private OrderService orderService;//订单表头
@Autowired
private OrderDetailedService orderDetailedService;//订单表身
/**
* pdf预览
* @param response HttpServletResponse
*/
@GetMapping(value = "/pdf/preview")
@ApiOperation(value="pdf预览")
public void preview(HttpServletResponse response,Integer id) {
OrderDto orderDto=orderService.findById(id);
List list=orderDetailedService.findAll(new OrderDetailedDto(){{setOrderId(id);}});
// 构造freemarker模板引擎参数,listVars.size()个数对应pdf页数
List> listVars = new ArrayList<>();
Map variables = new HashMap<>(4);
variables.put("title","订单明细");
variables.put("custName",orderDto.getCustomName());
variables.put("adr",orderDto.getAddress());
variables.put("tel",orderDto.getTel());
variables.put("list",list);
listVars.add(variables);
PdfUtil.preview(templateEngine,"pdfPage",listVars,response);
}
}
5.PDF模板(pdfPage.html)
注意事项:
1.尽可能把CSS样式放在这个模板里,外部引入可能会存在一些问题。
2.关于图片,切记一定要给完整路径,而非相对路径。如./uploadFile/logo.png 需要加上http://地址/uploadFile/logo.png
3.图片名称不能包含中文,否则会找不到路径(是由于编码为UTF8的原因)
位置
效果: