下面进入正题:
需求:根据List<对象>导出PDF。
想法:
- 因为之前导出过word,所以产生了一个想法就是先生成Word,然后整合为一个word,再转成PDF。这个想法进行到转PDF的时候,没有找到方法而放弃。
- 直接导出PDF,然后整和PDF,导出。(最后经过千辛万苦,九九八十一难,取得真经,并在Linux上测试成功)
废话不多说,下面是代码:
首先需要先引入Maven
<!--pdf itext 的jar依赖 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.1.1</version>
</dependency>
然后是Controller
private final static String PDF_TEMP_PATH = "template/pdf_template/pdfTemp.pdf";
private final static String FONT_CN = "font/simsun.ttc";
@GetMapping(value = "/export/pdf" , produces = "application/pdf;charset=UTF-8")
public void exportReplyDoc(HttpServletResponse response){
List<OrderInfo> list = orderInfoService.list(Wrappers.<OrderInfo>query().lambda().last("limit 5"));
List<PdfReader> readers = Lists.newArrayList();
for (int i = 0; i < list.size(); i++) {
OrderInfo info = list.get(i);
//将info对象转换为String[]
String[] str = modelConvertArray(info);
PdfReader pdfReader =
ExportPDF.fillTemplate(str, PDF_TEMP_PATH,FONT_CN);
readers.add(pdfReader);
}
//合并导出的PDF
ExportPDF.combinPdf(response,readers);
}
public static String[] modelConvertArray (OrderInfo info) {
//该方法是将对象转换成 String[] ,自行转换即可;
}
最后重点util(记下来要考的!)
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import lombok.extern.log4j.Log4j;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
@Log4j
public class ExportPDF {
/**
* 使用模板生成PDF
*
* @param str 充填表格的数据
* @param templatePath 模板路径
* @param fontCn 中文包
*/
public static PdfReader fillTemplate(String[] str, String templatePath ,String fontCn) {
PdfReader reader ;
ByteArrayOutputStream bos;
PdfStamper stamper;
try {
reader = new PdfReader(templatePath);// 读取pdf模板
bos = new ByteArrayOutputStream();
stamper = new PdfStamper(reader, bos);
AcroFields form = stamper.getAcroFields();
int i = 0;
java.util.Iterator<String> it = form.getFields().keySet().iterator();
//设置中文字体,如果不设置部分中文不显示。
ExportPDF exportPDF = new ExportPDF();
BaseFont bf = BaseFont.createFont(fontCn + ",1",
BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
form.addSubstitutionFont(bf);
while (it.hasNext()) {
String name = it.next().toString();
form.setField(name, str[i++]);
}
stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true
stamper.close();
Document doc = new Document();
doc.open();
PdfReader pdfReader = new PdfReader(bos.toByteArray());
doc.close();
return pdfReader;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 合并 pdf
*
* @param readers 所有要合并的PDF的集合
* @param response
* @throws Exception
*/
public static void combinPdf( HttpServletResponse response, List<PdfReader> readers) {
try {
String targetFilename = "案件";
response.setContentType("application/pdf;");
response.setHeader("Content-disposition", "filename=" + new String(targetFilename.getBytes("GBK"), "ISO8859-1"));
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
document.open();
PdfContentByte cb = writer.getDirectContent();
int pageOfCurrentReaderPDF = 0;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();
while (iteratorPDFReader.hasNext()) {
PdfReader pdfReader = iteratorPDFReader.next();
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
document.newPage();
pageOfCurrentReaderPDF++;
PdfImportedPage page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
cb.addTemplate(page, 0, 0);
}
pageOfCurrentReaderPDF = 0;
}
document.close();
writer.close();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}
}
碰到的BUG
1、关于导出文字部分不显示的问题,就需要加入字体了 simsun.ttc 这个字体可以在你电脑的
C:\Windows\Fonts 目录下找到。然后复制出来,放到 resources 目录下就可以读取到文件了;
PDF模板也是相同的方法,放到resources 目录下即可;
2、为什么放到目录下还是不行呢?报空指针??
打包即可,代码运行时读取的是target目录下的文件。如果报错,打包试试吧。
3、打包之后报文件损坏的错误,需要在pom文件中如下设置
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>ttc</nonFilteredFileExtension>
<-- 如下 -->
<build>
<plugins>
<plugin>
<!--默认:spring-boot热部署-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>docx</nonFilteredFileExtension>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>ttc</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>