背景:在前后端调试项目的时候,如果pdf有100页。一次性将流全部返回,那么在前端渲染的时候会非常缓慢,影响客户体验。
思路:能否通过分页的方式,一次返回10页,分10次返回。
1.引入jar包 pdfbox-app1.8.10
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-app</artifactId>
<version>1.8.10</version>
</dependency>
2.建一个util方法
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import java.io.*;
import java.util.List;
/**
* @author:shiyx
* @date:2020/12/01
* @description:
*/
public class PdfUtil {
/**
* 分页获取pdf文件
*
* @param path pdf路径
* @param start 开始页
* @param end 结束页
* @param output 输出流
* @return
*/
public static Integer pdfMerge(String path,Integer start, Integer end, OutputStream output) {
Integer numberOfPages = 0;
//存储分页的pdf数据
PDDocument returnPDD = new PDDocument();
try {
//解析pdf原始文件
PDDocument pdf = PDDocument.load(new File(path));
//获取pdf中的所有页
List allPages = pdf.getDocumentCatalog().getAllPages();
//获取此pdf的总页数
numberOfPages = allPages.size();
//如果结束页比总页数小,则说明pdf已经加载完毕
if(end > numberOfPages ){
end = numberOfPages;
}
for (int i=start ; i <end; i++){
//获取pdf中所需的页面
PDPage pdPage = (PDPage) allPages.get(i);
//添加到返回结果
returnPDD.addPage(pdPage);
}
//将返回结果设置在response流中返回
returnPDD.save(output);
} catch (Exception e){
e.getMessage();
}finally {
try {
returnPDD.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return numberOfPages;
}
}
3.在controller中调用
/**
* 分页获取pdf资源
*
* @param response
*/
@GetMapping(value = "/link/file")
public void getInsightFileStream(Integer pageNo, Integer pageSize, String docPath, HttpServletResponse response) {
Integer pdfSize = 0;
Integer start = (pageNo - 1) * pageSize;
Integer end = pageSize * pageNo;
ServletOutputStream outputStream = null;
try {
response.setContentType("application/pdf");
outputStream = response.getOutputStream();
pdfSize = PdfUtil.pdfMerge(docPath, start, end, outputStream);
} catch (IOException e) {
e.printStackTrace();
}
//将pdf总页数放在head中返回
response.addHeader("pdf-size",pdfSize.toString());
}
4.在postman中掉该方法
5.查看返回结果
ps:
1.因为返回的流是给前端用的,所以没有做下载文件名格式化。
2.报告一共28页,1-15结果是15页,16-30结果是13页