有小老弟网上扒的PDF导出,效率之低,给我惊讶到了…画Freemarker模板给我看的…
1、绘制导出模板
😺 打开WPS或者Word
😺 1点击插入,2选择形状
😺 选择矩形或者线条进行绘制,自由绘制线粗细及背景色
😺 以下为绘制好的示范模板:
😺 把word转换为pdf再导入Adobe_Acrobat_X_Pro
😺 添加新域
😺 选择文本域就能满足大多数情况,看具体模板需求
😺 直接把域放在模板对应位置即可
😺 文本域属性调整
😺 域处理完毕之后,重新保存为PDF即可
代码处理
😺 依赖
<!-- pdf模板导出 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.6</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
😺 控制层
/**
* pdf导出
*
* @throws Exception
* @author 摸鱼码长
*/
@GetMapping("/pdf_export")
@ApiOperation(value = "pdf导出")
public void printPdf(HttpServletResponse response) throws Exception {
// 获取数据源
HashMap data = new HashMap<>();
data.put("Text1", "value");
String downloadName = "林深不见鹿.pdf";
String templatePath = "/thisIsExUrl";
OutputStream outputStream = null;
try {
response.setContentType("application/pdf");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "inline;fileName=" + URLEncoder.encode(downloadName, "UTF-8")); // 预览
// 获取outputStream
outputStream = response.getOutputStream();
// 生成pdf流输出到response
ItextPdfUtil.generatePDF(templatePath, outputStream, data);
} catch (Exception e) {
log.error("-===== ::: something ERROR ", e);
throw new RuntimeException("Buz log ..");
} finally {
if (outputStream != null) {
outputStream.close();
}
}
}
😺 核心方法
/**
* 生成pdf流输出到response
*
* @param templatePdfPath url
* @param outputStream outputStream
* @param data dataResource
* @author 摸鱼码长
*/
public static void generatePDF(String templatePdfPath, OutputStream outputStream, HashMap data) {
ByteArrayOutputStream byteArrayOutputStream = null;
PdfReader reader = null;
try {
PdfReader.unethicalreading = true;
reader = new PdfReader(templatePdfPath);
byteArrayOutputStream = new ByteArrayOutputStream();
PdfStamper ps = new PdfStamper(reader, byteArrayOutputStream);
ArrayList<BaseFont> fontList = new ArrayList<>();
AcroFields fields = ps.getAcroFields();
fields.setGenerateAppearances(true);
fields.setSubstitutionFonts(fontList);
transformRegular(ps, fields, data);
ps.setFormFlattening(true);
ps.close();
reader.close();
outputStream.write(byteArrayOutputStream.toByteArray());
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 表单域填充
*
* @param stamper
* @param form
* @param dataMap
* @throws IOException
* @throws DocumentException
* @author 摸鱼码长
*/
public static void transformRegular(PdfStamper stamper, AcroFields form, HashMap dataMap) throws IOException, DocumentException {
if (dataMap == null || dataMap.size() == 0) {
return;
}
// 设置中文显示
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
String key = "";
form.addSubstitutionFont(bfChinese);
Iterator ekey = dataMap.keySet().iterator();
while (ekey.hasNext()) {
key = ekey.next().toString();
try {
//非空放入
if (dataMap.get(key) != null) {
if (dataMap.get(key) instanceof HashMap) {
HashMap<String, String> fieldMap = (HashMap<String, String>) dataMap.get(key);
if ("img".equals(fieldMap.get("type"))) {
String content = fieldMap.get("content");
//如果图片地址为空,或不存在则不填充
if (StringUtils.isBlank(content)) {
continue;
}
URL url = new URL(content);
if ("file".equals(url.getProtocol())) {
if (!new File(url.toURI()).exists()) {
continue;
}
}
// 通过域名获取所在页和坐标,左下角为起点
int pageNo = form.getFieldPositions(key).get(0).page;
Rectangle signRect = form.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// 读图片
Image image = Image.getInstance(content);
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
} else {
form.setField(key, dataMap.get(key).toString());
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}