解决的问题

有些时候我们需要在项目中展示PDF,但是直接在浏览器中加入PDF展示的插件,存在兼容性问题,某些浏览器显示效果不理想,所以我们可以将PDF转为图片,然后已图片的方式展示,效果很好。

那么怎么将PDF转为图片呢?有两种方式:

产品 特点
Apache 的 PDF box 免费;速度稍慢一点,但可以接受
E-iceblue 的 Spire.PDF for Java 转换效果很好;速度快;功能强大,支持转多种格式;收费

Spire.PDF for Java 的转换效果很好,但是如果不购买,转换过后会添加一些水印文字

参考链接:https://www.cnblogs.com/Yesi/p/11233238.html

PDF Box的使用

<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>pdf2dom</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.12</version>
</dependency>

多页PDF生成多张图片

新建一个 PdfUtil 工具类

public class PdfUtil {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PdfUtil.class);

    /***
* PDF文件转PNG图片,全部页数
*
* @param pdfFilePath pdf完整路径
* @param dpi dpi越大转换后越清晰,相对转换速度越慢
*/
public static void pdf2Image(String pdfFilePath, int dpi) {
File file = new File(pdfFilePath);
PDDocument pdDocument;
try {
String imgPdfPath = file.getParent();
int dot = file.getName().lastIndexOf('.');
// 获取图片文件名
String imagePdfName = file.getName().substring(0, dot); pdDocument = PDDocument.load(file);
PDFRenderer renderer = new PDFRenderer(pdDocument);
/* dpi越大转换后越清晰,相对转换速度越慢 */
PdfReader reader = new PdfReader(pdfFilePath);
int pages = reader.getNumberOfPages();
StringBuffer imgFilePath;
for (int i = 0; i < pages; i++) {
String imgFilePathPrefix = imgPdfPath + File.separator + imagePdfName;
imgFilePath = new StringBuffer();
imgFilePath.append(imgFilePathPrefix);
imgFilePath.append("_");
imgFilePath.append((i + 1));
imgFilePath.append(".png");
File dstFile = new File(imgFilePath.toString());
BufferedImage image = renderer.renderImageWithDPI(i, dpi);
ImageIO.write(image, "png", dstFile);
}
log.info("PDF文档转PNG图片成功!");
} catch (IOException e) {
e.printStackTrace();
}
} }

多页PDF组合成一张图片

public class PdfUtil {

    public static final int DEFAULT_DPI = 150;

    /**
* pdf转图片
* 多页PDF会每页转换为一张图片,下面会有多页组合成一页的方法
*
* @param pdfFile pdf文件路径
* @param outPath 图片输出路径
* @param dpi 相当于图片的分辨率,值越大越清晰,但是转换时间变长
*/
public static void pdf2multiImage(String pdfFile, String outPath, int dpi) {
if (ObjectUtil.isEmpty(dpi)) {
// 如果没有设置DPI,默认设置为150
dpi = DEFAULT_DPI;
}
try (PDDocument pdf = PDDocument.load(new FileInputStream(pdfFile))) {
int actSize = pdf.getNumberOfPages();
List<BufferedImage> picList = Lists.newArrayList();
for (int i = 0; i < actSize; i++) {
BufferedImage image = new PDFRenderer(pdf).renderImageWithDPI(i, dpi, ImageType.RGB);
picList.add(image);
}
// 组合图片
ImageUtil.yPic(picList, outPath);
} catch (IOException e) {
e.printStackTrace();
}
}
}

新建 ImageUtil 类

public class ImageUtil {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImageUtil.class);

    /**
* 将宽度相同的图片,竖向追加在一起 ##注意:宽度必须相同
*
* @param picList 文件流数组
* @param outPath 输出路径
*/
public static void yPic(List<BufferedImage> picList, String outPath) {// 纵向处理图片
if (picList == null || picList.size() <= 0) {
log.info("图片数组为空!");
return;
}
try {
// 总高度
int height = 0,
// 总宽度
width = 0,
// 临时的高度 , 或保存偏移高度
offsetHeight = 0,
// 临时的高度,主要保存每个高度
tmpHeight = 0,
// 图片的数量
picNum = picList.size();
// 保存每个文件的高度
int[] heightArray = new int[picNum];
// 保存图片流
BufferedImage buffer = null;
// 保存所有的图片的RGB
List<int[]> imgRgb = new ArrayList<int[]>();
// 保存一张图片中的RGB数据
int[] tmpImgRgb;
for (int i = 0; i < picNum; i++) {
buffer = picList.get(i);
// 图片高度
heightArray[i] = offsetHeight = buffer.getHeight();
if (i == 0) {
// 图片宽度
width = buffer.getWidth();
}
// 获取总高度
height += offsetHeight;
// 从图片中读取RGB
tmpImgRgb = new int[width * offsetHeight];
tmpImgRgb = buffer.getRGB(0, 0, width, offsetHeight, tmpImgRgb, 0, width);
imgRgb.add(tmpImgRgb);
}
// 设置偏移高度为0
offsetHeight = 0;
// 生成新图片
BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < picNum; i++) {
tmpHeight = heightArray[i];
if (i != 0) {
// 计算偏移高度
offsetHeight += tmpHeight;
}
// 写入流中
imageResult.setRGB(0, offsetHeight, width, tmpHeight, imgRgb.get(i), 0, width);
}
File outFile = new File(outPath);
// 写图片
ImageIO.write(imageResult, "png", outFile);
} catch (Exception e) {
e.printStackTrace();
}
} }

Java中PDF的转换(图片)与展示的更多相关文章

  1. java中汉字自动转换成拼音

    java中汉字自动转换成拼音 1.需要下载jar包 pinyin4j.2.5.0.jar ,加入到WEB-INF下的lib里边,右键add to bulid path. 2.[代码]PinYinUti ...

  2. java中调用kettle转换文件

    java中调用kettle转换文件 通过命令行也能够调用,然后java中调用命令行代码也能够.这样没有和java代码逻辑无缝集成.本文说明kettle5.1中假设通过其它API和java代码无缝集成: ...

  3. java中的时区转换

    目录 java中的时区转换 一.时区的说明 二.时间的表示 三.时间戳 四.Date类和时间戳 五.java中的时区转换 java中的时区转换 一.时区的说明 地球表面按经线从东到西,被划成一个个区域 ...

  4. JAVA中pdf转图片的方法

    JAVA中实现pdf转图片可以通过第三方提供的架包,这里介绍几种常用的,可以根据自身需求选择使用. 一.icepdf.有收费版和开源版,几种方法里最推荐的.转换的效果比较好,能识别我手头文件中的中文, ...

  5. java读取pdf文本转换html

    补充:一下代码基于maven,现将依赖的jar包单独导出 地址:pdf jar 完整代码地址 也就两个文件 java读取pdf中的纯文字,这里使用的是pdfbox工具包 maven引入如下配置 < ...

  6. Java 设置PDF平铺图片背景(水印)

    一.概述及环境准备 本文介绍使用免费版PDF库-Free Spire.PDF for Java加载图片来设置成PDF平铺图片背景的效果,也可以作为平铺图片水印来使用:编辑代码前,需要先导入jar文件, ...

  7. 填坑:Java 中的日期转换

    我们之前讨论过时间,在Java 中有一些方法会出现横线?比如Date 过期方法. 参考文章:知识点:java一些方法会有横线?以Date 过期方法为例 Java中的日期和时间处理方法 Date类(官方 ...

  8. Java中数据类型默认转换和强制类型转换

    默认转换: a:由低到高一次为:(byte   short    char  )---int ---long ---float --- double b:注意:byte   short    char ...

  9. 【图片识别】Java中使用tess4J进行图片文字识别(支持中文)(转)

    http://blog.csdn.net/wsk1103/article/details/54173282 java中识别文字比较简单,使用的软件是tesseractocr(使用的版本是3.02,3以 ...

  10. JAVA中时间格式转换

    1.将任意日期格式的字符串转换为指定格式的字符串 //默认格式 String s1 = "20190110133236"; //给定格式 String s2 = "201 ...

随机推荐

  1. 基于信通院 Serverless 工具链模型的实践:Serverless Devs

    简介: Serverless Devs 作为开源开放的开发者工具,参编中国信通院<基于无服务器架构的工具链能力要求>标准,为行业统一规范发挥助推作用!​ 作者 | 江昱(阿里云 Serve ...

  2. 贝壳基于 Flink 的实时计算演进之路

    简介: 贝壳找房在实时计算之路上的平台建设以及实时数仓应用. 摘要:贝壳找房大数据平台实时计算负责人刘力云带来的分享内容是贝壳找房的实时计算演进之路,内容如下: 发展历程 平台建设 实时数仓及其应用场 ...

  3. 数仓架构的持续演进与发展 — 云原生、湖仓一体、离线实时一体、SaaS模式

    简介: 数据仓库概念从1990年提出,经过了四个主要阶段.从最初的数据库演进到数据仓库,到MPP架构,到大数据时代的数据仓库,再到今天的云原生的数据仓库.在不断的演进过程中,数据仓库面临着不同的挑战. ...

  4. [FE] iframe 相关选项 x-frame-options: 设置 meta 标签无效 & helmet

    The X-Frame-Options HTTP 响应头是用来给浏览器 指示允许一个页面 可否在 <frame>, <iframe>, <embed> 或者 < ...

  5. [Py] Python 字符串 str 和 字节 bytes 的互转

    字节转字符串: st = str(data, encoding = "utf8") print(st) print(type(str)) # <class 'str'> ...

  6. github只下载某个文件或文件夹(使用GitZip插件)

    安装GitZip插件 (此安装过程需要梯子(不懂"梯子",百度一下就明白)) 1. 打开插件管理页面 方法一:打开Chrome浏览器(Edge浏览器同理),在Chrom地址栏输入c ...

  7. JavaWeb 中 “转发”与 “重定向”的区别

    JavaWeb 中 "转发"与 "重定向"的区别 每博一文案 人生的常态,就是有聚有散,有得有失,就像山峰一样,总有高低,起伏不断. 曾经,我们是鲜衣怒马的少年 ...

  8. linux基础命令及bash shell特性

    linux基础命令及bash shell特性 目录 linux基础命令及bash shell特性 1.linux基础命令 1.1 查看内核版本和linux发行版本 1.2 查看服务器硬件信息 1.3 ...

  9. 09. C语言内嵌汇编代码

    C语言函数内可以自定义一段汇编代码,在GCC编译器中使用 asm 或 __asm__ 关键词定义一段汇编代码,并可选添加volatile关键字,表示不要让编译器优化这段汇编代码. 内嵌汇编代码格式如下 ...

  10. Java异步编程CompletableFuture

    Java 通过多线程可以实现异步编程,下面是一个使用 Java 多线程实现异步编程的示例: public class AsyncDemo { public static void main(Strin ...