Java根据模板导出PDF文件
在日常使用中,会涉及到将数据库中的数据进行计算处理,并将数据写在PDF模板
1 封装数据
代码是伪代码,不能导入直接运行,简单的看一下很容理解
public Map<String, Map<String, Object>> getScorePackage(String type, String userId) {
//查询出多条数据,使用map,将数据封装起来,便于批量下载PDF
Map<String, Map<String, Object>> map = new HashMap<>();
List<ScorePo> record = scoreMapper.getScorePackage(userId, BaseCommonUntil.getHarbourTermService().getId());
for (ScorePo n : record) {
if (n != null) {
Map<String, Object> dataMap = new HashMap<>();
//模板的地址和新pdf的存储地址
//模板名称
dataMap.put("templatePath", "成绩模板.pdf");
//pdf文件属性
dataMap.put("title", "成绩单");
dataMap.put("author", "****有限公司");
dataMap.put("subject", "成绩单");
dataMap.put("keywords", "report");
dataMap.put("creator", "****有限公司");
//表单属性,此处的属性,就是赋值给PDF模板的form表单的值
dataMap.put("name", n.getName() == null ? "" : n.getName());
dataMap.put("school", n.getSchoolName() == null ? "" : n.getSchoolName());
dataMap.put("courseName", n.getChineseName() == null ? "" : n.getChineseName());
dataMap.put("teacher", n.getTeacherName() == null ? "" : n.getTeacherName())
map.put(n.getName(), dataMap);
}
}
return map;
}
2 将PDF通过压缩包形式下载
@ApiOperation(value = "下载成绩单")
@GetMapping(value = "export")
public void export(@RequestParam(name = "type") String type, HttpServletRequest request, HttpServletResponse response) throws IOException {
String outputFileName = "score--" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".zip";
// 设置response参数
response.reset();
response.addHeader("access-control-allow-origin", "*");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setContentType("content-type:octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + new String((outputFileName).getBytes(), "iso-8859-1"));
ServletOutputStream out = response.getOutputStream();
ZipArchiveOutputStream zous = new ZipArchiveOutputStream(out);
zous.setUseZip64(Zip64Mode.AsNeeded);
//此处的数据就是 1 中封装的map数据***********************
Map<String, Map<String, Object>> map = scoreService.getScorePackage(type,BaseCommonUntil.getUser().getId());
for(Map.Entry<String, Map<String, Object>> entry : map.entrySet()){
String mapKey = entry.getKey();
Map<String, Object> value = entry.getValue();
//此处是具体的将数据封装到 PDF 模板当中
ByteArrayOutputStream baoss = PDFBuilder.fillTemplate(value);
byte[] bytes = baoss.toByteArray();
//设置文件名
ArchiveEntry en = new ZipArchiveEntry(mapKey+".pdf");
zous.putArchiveEntry(en);
zous.write(bytes);
zous.closeArchiveEntry();
if (baoss != null) {
baoss.close();
}
}
if(zous!=null) {
zous.close();
}
}
3 将数据插入PDF具体操作
package org.begete.modules.harbour.base.untils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ResourceUtils;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class PDFBuilder {
public static ByteArrayOutputStream fillTemplate(Map<String, Object> dataMap) throws IOException {// 利用模板生成pdf
// 模板路径
String templatePath = dataMap.get("templatePath").toString();
ClassPathResource classPathResource = new ClassPathResource("template/"+templatePath);
InputStream inputStream = classPathResource.getInputStream();
PdfReader reader;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper stamper;
try {
reader = new PdfReader(inputStream);// 读取pdf模板
bos = new ByteArrayOutputStream();
stamper = new PdfStamper(reader, bos);
// 创建字体显示中文
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//查询出模板文件的表单域
Font font = new Font(bfChinese, 72,Font.BOLD);
AcroFields form = stamper.getAcroFields();
Iterator<String> it = form.getFields().keySet().iterator();
while (it.hasNext()) {
String name = it.next().toString();
if(!"signature_confirm".equals(name)){
form.setFieldProperty(name,"textfont",bfChinese,null);
form.setField(name, dataMap.get(name).toString());
}else{
}
}
// 如果为false那么生成的PDF文件还能编辑,一定要设为true
stamper.setFormFlattening(true);
stamper.close();
// 1.创建一个ducument
Document document = new Document();
// 2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中
// 创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径
/*PdfWriter writer = PdfWriter.getInstance(document, out);
//PDF版本(默认1.4)
writer.setPdfVersion(PdfWriter.PDF_VERSION_1_6);*/
document.open();
// 设置属性
// 标题
document.addTitle("成绩单");
// 作者
document.addAuthor("***有限公司");
// 主题
document.addSubject("成绩单");
// 关键字
document.addKeywords("report");
// 创建时间
document.addCreationDate();
// 应用程序
document.addCreator("***有限公司");
// 5.关闭文档
document.close();
bos.close();
reader.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
return bos;
}
}
4 涉及到的包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.18</version>
</dependency>
需要对PDF文件进行处理
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
具体的PDF模板我没有放上来,具体可以百度搜索PDF编辑器,form表单