当前位置: 首页 > news >正文

Java SpringBoot实现PDF转图片

不是单页图片,是多页PDF转成一张图片的逻辑。

我这里的场景是PDF转成图片之后返回给前端,前端再在图片上实现签字,并且可拖拽的逻辑,就是签订合同的场景。

但是这里只写后端多页PDF转图片的逻辑。

先说逻辑,后面直接上代码,大致分为以下几步:

  1. 读取PDF文件(我的代码里是将在线的URL转成InputStream了)
  2. 按PDF的页面循环计算图片的宽度和高度,其中宽度为PDF最宽的那一页的宽度(毕竟有的PDF比较骚,可能一页是横的,一页是竖的),高度为所有页面加起来的高度
  3. 用Graphics2D绘制
  4. 将Graphics2D的绘制结果输出为图片(只要有outputStream都好说,我这里是输出成base64给前端了,没什么存起来的必要)

好了,直接上代码:

先在pom.xml导入依赖:

		<!--   pdf读取     --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.1</version></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.1</version></dependency>
	public String getSinglePicBase64Contracts(String fileUrl) throws IOException {byte[] pdfBytes = HttpUtil.createGet(fileUrl).execute().bodyBytes();InputStream inputStream = new ByteArrayInputStream(pdfBytes);PDDocument doc = PDDocument.load(inputStream);PDFRenderer pdfRenderer = new PDFRenderer(doc);List<BufferedImage> imageList = new ArrayList<>(doc.getNumberOfPages());int maxWidth = 0;int totalHeight = 0;for (int i = 0; i < doc.getNumberOfPages(); i++) {BufferedImage image = pdfRenderer.renderImage(i, 1.25f);imageList.add(image);if (image.getWidth() > maxWidth) {maxWidth = image.getWidth();}totalHeight += image.getHeight();}// 绘制结果BufferedImage result = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = result.createGraphics();int nowHeight = 0;for (BufferedImage bufferedImage : imageList) {// padding 为页面的左边距int padding = (maxWidth - bufferedImage.getWidth()) / 2;g2d.drawImage(bufferedImage, padding, nowHeight, null);nowHeight += bufferedImage.getHeight();}ByteArrayOutputStream outputStream =  new ByteArrayOutputStream();ImageIO.write(result, "png", outputStream);String singlePicBase64 = "data:image/png;base64," + Base64.encodeBase64String(outputStream.toByteArray());return singlePicBase64;}
http://www.lryc.cn/news/420391.html

相关文章:

  • elasticsearch SQL:在Elasticsearch中启用和使用SQL功能
  • Java 并发编程:线程变量 ThreadLocal
  • 【OpenHarmony4.1 之 U-Boot 2024.07源码深度解析】018 - init_sequence_f 各函数源码分析(二)
  • LVS原理——详细介绍
  • MYSQL 5.7.36 等保 建设记录
  • fatal: unable to access ‘https://github.com/xxxxx
  • 从零开始的CPP(38)——递归与动态规划
  • 从战略到系统架构:信息系统设计的全面解析
  • GEE调用中国(China Land Cover Dataset,简称CLCD)1990-2022年30米分辨率的土地分类数据
  • 三十八、大数据技术之Kafka(1)
  • 将 Tcpdump 输出内容重定向到 Wireshark
  • 【Python蓝屏程序(管理员)】
  • OpenGL ES->GLSurfaceView绘制图形的流程
  • Linux OOM Killer详解
  • 2024rk(案例二)
  • 小红书爆文秘籍:ChatGPT助你从0到1创造热门内容!
  • django快速实现个人博客(附源码)
  • K8s部署篇之手动部署二进制高可用集群架构
  • 【Unity/XLua】xlua自带教程示例分析(6)—— lua协程
  • CV目标检测概述
  • 如何在notebook中运行nodejs
  • Mybatis学习-day19
  • IDEA构建SpringBoot多模块项目
  • 【前端】NodeJS:nvm
  • Docker网络模式及通信
  • 类模板实现实现Qt click/hover自定义操作
  • Arco Design:引领未来的Vue 3创意先锋,一键开启高效与美感并重的Web开发之旅!
  • 【MySQL】Linux下用C/C++链接MySQL数据库
  • Python金融量化专栏简介
  • 出行365:依托分布式数据库,让出行无忧 | OceanBase案例