前段时间,老板接到一个需求,说是某个小程序打开PDF文件加载太慢了?开发团队的同学一脸闷逼,大家不都是这样做的?提升服务器的带宽不就可以了么。
结果运维同学在提升了服务器带宽,增加了服务器内存之后,老板到客户面前去装X的时候,还是翻车了。所以就要求开发同学一定要解决这个问题。
我们日常使用的PDF,有两种形式
- 文档形式的PDF:通过Word文档或者PPT等内容导出生成的PDF。
- 图片形式的PDF:通过图片生成的PDF
根据这个思路,我们可以将PDF的每一页切分成一个图片,这样按照图片加载内容,总比直接加载一个一两百兆的PDF文件要加载的快吧,说干就干。下面我们就来看看如何去实现一个PDF文件的切分。
创建一个文件上传的接口
在这个接口中主要完成PDF文件的上传工作。
/**
* 通用上传请求(单个)
*/
@PostMapping("/uploadPdf")
@ResponseBody
public AjaxResult uploadFilePdf(MultipartFile file) throws Exception
{
try
{
String prefix = RuoYiConfig.getImageProxyPath();
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.uploadPdf(filePath, file);
String url = prefix + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
PDF文件切分操作
首先需要引入两个POM的依赖
编写一个接收PDF文件并且进行拆分的方法
/**
* 将PDF文档拆分成图像列表
*
* @param pdf PDF文件
*/
private static List
将图片切分成一个List
/**
* PDF分解图片文件
*
* @param pdf pdf文件
* @param outDir 输出文件夹
*/
public static List
保存图像到指定路径
/**
* 保存图像到指定文件
* @param image 图像
* @param filePath 文件路径
*/
public static void saveImageToFile(BufferedImage image, String filePath) throws IOException {
FileUtils.saveDataToFile(filePath,getBytes(image));
}
将数据保存到指定的路径
/**
* 将数据保存到指定文件路径
*/
public static void saveDataToFile(String filePath,byte[] data) throws IOException {
File file = new File(filePath);
if(!file.exists()){
file.createNewFile() ;
}
FileOutputStream outStream = new FileOutputStream(file);
outStream.write(data);
outStream.flush();
outStream.close();
}
最终通过这样的操作可以让PDF转换换成一张一张的图片。然后通过getList的方式去加载这些图片。就不会出现因为PDF文件过大而导致的加载缓慢的问题。