解决的问题

有些时候我们需要在项目中展示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. MaxCompute同步数据的网络配置

    MaxCompute可以通过数据集成加载不同数据源(例如:MySQL数据库等)数据,同样也可以通过数据集成把MaxCompute的数据导出到各种业务数据库.数据集成功能已经集成到DataWorks作为 ...

  2. 一文详解 Nacos 高可用特性

    简介: 我今天介绍的 Nacos 高可用,是 Nacos 为了提升系统稳定性而采取的一系列手段.Nacos 的高可用不仅仅存在于服务端,同时也存在于客户端,以及一些与可用性相关的功能特性中,这些点组装 ...

  3. 技术揭秘:实时数仓Hologres如何支持超大规模部署与运维

    ​简介:在本次评测中,Hologres是目前通过中国信通院大数据产品分布式分析型数据库大规模性能评测的规模最大的MPP数据仓库产品.通过该评测,证明了阿里云实时数仓Hologres能够作为数据仓库和大 ...

  4. Flink 最佳实践之使用 Canal 同步 MySQL 数据至 TiDB

    简介: 本文将介绍如何将 MySQL 中的数据,通过 Binlog + Canal 的形式导入到 Kafka 中,继而被 Flink 消费的案例. 一. 背景介绍 本文将介绍如何将 MySQL 中的数 ...

  5. Dapr 在阿里云原生的实践

    简介: Faas 场景下,比较吸引用户的是成本和研发效率,成本主要通过按需分配和极致的弹性效率来达成.而应用开发者期望通过 FaaS 提供多语言的编程环境,提升研发效率,包括启动时间.发布时间.开发的 ...

  6. dotnet 解析 TTF 字体文件格式

    在 Windows 下,可以使用 DX 提供的强大能力,调用 DX 读取 TTF 字体文件,获取字体文件的信息以及额外的渲染信息.特别是基于 DX 的 WPF 更是加了一层封装,使用 FontFami ...

  7. 还在用Jenkins?快来试试这款比Jenkins简而轻的自动部署软件!

    大家好,我是 Java陈序员. 在工作中,你是否遇到过团队中没有专业的运维,开发还要做运维的活,需要自己手动构建.部署项目? 不同的项目还有不同的部署命令,需要使用 SSH 工具连接远程服务器和使用 ...

  8. Ubuntu下MPICH的安装与配置

    原创直达链接 一.MPICH的下载与安装 MPI安装文件下载地址: 博客下载地址 或 官网地址 可以下载3.4.2版本的,本文就是3.4.2版本 1.解压: sudo tar - zxvf mpich ...

  9. anaconda3部署以及使用详解

    Anaconda3-2019.10-Linux-x86_64.sh 某次执行Python程序,其中两个错误信息如下: ImportError: libcblas.so.3: cannot open s ...

  10. .NET中特性+反射 实现数据校验

    .NET中特性+反射 实现数据校验 在.NET中,我们可以使用特性+反射来实现数据校验.特性是一种用于为程序中的代码添加元数据的机制.元数据是与程序中的代码相关联的数据,但不直接成为代码的一部分.通过 ...