kkFileView二开之pdf转图片接口

kkFileView二开系列文章:

  1. kkFileView二开之源码编译及部署
  2. kkFileView二开之内外网转换
  3. kkFileView二开之word转pdf接口
  4. kkFileView二开之Excel转pdf接口
  5. kkFileView二开之pdf转图片接口
  6. kkFileView二开之企业级安全问题处理
    对应二开代码仓库:https://gitee.com/wbj_1/kk-file-view

1 kkFileView源码下载及编译

前文 【kkFileView二开之源码编译及部署】 已完成了kkFileView源码二开的基础准备。

2 Pdf转图片接口

2.1 背景

在实际工作过程中,存在Pdf转图片的需求,比如人员证书,通过pdf模板填充后,生成对应的图片。

2.2 分析

kkFiewView 针对pdf在线预览会有两种方式,一种是转换为图片进行预览,一种是保留原始pdf格式进行预览,此处可以调用kkfiewView底层中pdf转图片预览的方式,实现对应的接口

2.2 接口开发

2.2.1 编写Pdf转图片方法

在cn.keking.service.FileHandlerService.java 中,新增转换方法:

/**
     * pdf转换为图片
     * @param pdfFilePath
     * @param fileAttribute
     * @return
     * @throws Exception
     */
    public List<String> pdf2jpgBase64(String pdfFilePath,FileAttribute fileAttribute) throws Exception {
        String filePassword = fileAttribute.getFilePassword();
        PDDocument doc = null;
        List<String> imageFile = new ArrayList<>();
        try {
            File pdfFile = new File(pdfFilePath);
            if (!pdfFile.exists()) {
                return null;
            }
            doc = Loader.loadPDF(pdfFile, filePassword);
            doc.setResourceCache(new NotResourceCache());
            int pageCount = doc.getNumberOfPages();
            PDFRenderer pdfRenderer = new PDFRenderer(doc);
            for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
                BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, ConfigConstants.getPdf2JpgDpi(), ImageType.RGB);
                imageFile.add(ImgUtil.toBase64DataUri(image,"jpg"));
            }
        } catch (IOException e) {
            logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
            throw new Exception(e);
        } finally {
            if (doc != null) {   //关闭
                doc.close();
            }
        }
        return imageFile;
    }

2.2.2 编写转换接口

在cn.keking.web.controller包下,新增ConvertController.java 文件

package cn.keking.web.controller;

import cn.hutool.core.io.FileUtil;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.FileType;
import cn.keking.service.FileHandlerService;
import cn.keking.service.OfficeToPdfService;
import cn.keking.utils.KkFileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件转换接口
 */
@Controller
public class ConvertController {
    private final String fileDir = ConfigConstants.getFileDir();
    //临时目录
    private final String tempPath = "temp" + File.separator;
    @Autowired
    private OfficeToPdfService officeToPdfService;
    @Autowired
    private FileHandlerService fileHandlerService;
    private static final String FILE_DIR = ConfigConstants.getFileDir();
    
    /**
     * pdf转换为图片
     * @param req
     * @param rep
     * @param file
     */
    @PostMapping("/pdf2Image")
    @ResponseBody
    public Map<String,Object> pdf2Image(HttpServletRequest req, HttpServletResponse rep, @RequestParam("file") MultipartFile file) {
        Map<String,Object> result = new HashMap<>();
        FileAttribute fileAttribute = new FileAttribute();
        String fullFileName = file.getOriginalFilename();
        fileAttribute.setType(FileType.typeFromFileName(fullFileName));
        fileAttribute.setName(fullFileName);
        fileAttribute.setSuffix(KkFileUtils.suffixFromFileName(fullFileName));
        try {
            String pdfName = fullFileName.substring(0, fullFileName.lastIndexOf(".") + 1) + "pdf";
            String outFilePath = FILE_DIR + pdfName;
            FileUtil.writeFromStream(file.getInputStream(),outFilePath);
            List<String> imageUrls = fileHandlerService.pdf2jpgBase64(outFilePath, fileAttribute);
            result.put("code",200);
            result.put("msg","转换成功");
            result.put("data",imageUrls);
        }catch (Exception e){
            e.printStackTrace();
            result.put("code",500);
            result.put("msg","pdf转换图片异常:"+e.getMessage());
        }
        return result;
    }
}

2.3 接口测试

2.3.1 Pdf文件准备

在这里插入图片描述

2.3.2 pdf2Image

使用Apifox新建接口,按如下方式配置,并点击发送
注意:通过源码分析可知,在Pdf进行预览过程中,预览速度会随着pdf的大小不同而不同,pdf越大,则接口速度越慢,因为是一次性将对应的pdf全部转换后返回至前端的。
在这里插入图片描述
结果格式化效果(pdf文件有85页,所以data中有85条数据)
在这里插入图片描述
按如下方式,将生成的每一条数据写入到img标签中

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta charset="utf-8" />
	<title>New Document</title>
</head>
<body>
	<img src="data标签中的每一行数据" alt="" />
</body>
</html>

在浏览器中打开编写的html文件,如效果图所示,即为转换后的base64图片
在这里插入图片描述

3 部署

可参考 【kkFileView二开之源码编译及部署】 文档中,【部署】目录下的方式,根据部署的平台选择合适的方式进行部署。

### KKFileView 查看 PDF图片加载性能优化 #### 一、分析原因 文件预览插件如KKFileView在处理大尺寸PDF文档或高分辨率图像时可能出现加载缓慢的情况。这通常是因为浏览器端渲染资源消耗较大所致[^1]。 #### 、前端层面的解决方案 ##### 1. 使用Web Worker异步加载 通过创建新的线程来执行耗时操作可以有效减少主线程压力,提高页面响应速度。对于大型文件可考虑采用分块读取的方式逐步展示内容给用户。 ```javascript let worker = new Worker('worker.js'); worker.postMessage({action:'loadPdf',path:'/files/sample.pdf'}); ``` ##### 2. 延迟加载技术(Lazy Load) 仅当元素进入视口范围内才始请求数据并显示出来,在滚动过程中动态调整可见区域内的对象优先级从而节省带宽和内存占用。 ```html <img data-src="image.jpg" class="lazy"/> <script> document.querySelectorAll('.lazy').forEach((img)=>{ img.src=img.getAttribute('data-src'); }); </script> ``` #### 三、服务端支持措施 ##### 1. 启用HTTP缓存机制 合理设置Expires/Cache-Control头部字段使得相同URL下的静态资源能够在客户端本地持久化存储一段时间内无需重复下载。 ```nginx location ~* \.(pdf|jpg)$ { expires max; } ``` ##### 2. 提供缩略图选项 针对原始高清素材预先生成低质量版本用于初次快速浏览,待用户点击查看原图后再发起正式获取流程。 ```php <?php // PHP伪代码示意如何根据需求返回不同清晰度的图片 if($request->isThumbnail()){ echo file_get_contents("thumbnail_{$filename}"); }else{ echo file_get_contents($filename); } ?> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值