Word 文档转换 PDF、图片

工作有需要 Word 文档转换 PDF、图片 的场景,我们来看看 Java 开发中怎么解决这个问题的。

Word 转 PDF

Word 转 PDF 分为商用 Aspose 方案和开源 Apache POI+iText 方案。

Aspose 方案

这种方式在目前来看应该是最好的,无论是转换的速度还是成功的概率,还支持的文件类型。

由于 Aspose 并非开源软件,不会在 Maven 公开依赖,故我们要手动加入到 Maven 管理中去。

<!-- Word2PDF -->
<dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>15.8</version><scope>system</scope><systemPath>${project.basedir}/jar/aspose-words-15.8.0-jdk16.jar</systemPath>
</dependency>

添加依赖

因为是手动添加的包,MANIFEST.MF 也要加入,不然启动程序的时候不知道要加入这个 jar 包。增加一个manifestEntries节点:

<manifestEntries><!--MANIFEST.MF 中 Class-Path 加入资源文件目录 --><Class-Path>lib/aspose-words-15.8.0-jdk16.jar</Class-Path>
</manifestEntries>

新增于 pom.xml 的<plugins>位置如图:
在这里插入图片描述
拷贝 jar 包,除了 runtime 的还有刚新家的 system 包,新增一个copy-dependencies2

<execution><id>copy-dependencies2</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory><includeScope>system</includeScope></configuration></execution>

新增于 pom.xml 的<plugins>位置如图:
在这里插入图片描述

转换程序

import com.aspose.words.Document;
import com.aspose.words.ImageSaveOptions;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;/*** <a href="https://www.cnblogs.com/excellencesy/p/11603892.html">...</a>* <a href="https://blog.csdn.net/weixin_44605704/article/details/102572130">...</a>*/
public class AsposeUtil {/*** Word 转 PDF** @param wordPath Word 路径* @param pdfPath  PDF 路径*/public static void word2pdf(String wordPath, String pdfPath) {AsposeUtil.getLicense();try (FileOutputStream os = new FileOutputStream(pdfPath)) {long old = System.currentTimeMillis();//设置一个字体目录(必须设置,否则生成的pdf乱码)下面这行代码不加的话在windows系统下生成的pdf不存在乱码问题,但是在linux系统下会乱码,linux下乱码解决方案请看后面的解决方案//FontSettings.setFontsFolder("/usr/share/fonts/chinese", false);new Document(wordPath).save(os, SaveFormat.PDF);System.out.println("word2pdf共耗时:" + (System.currentTimeMillis() - old) / 1000.0 + "秒");} catch (Exception e) {e.printStackTrace();}}public static void word2img(String wordPath, String outputDir) {AsposeUtil.getLicense();try {long old = System.currentTimeMillis();Document doc = new Document(wordPath);// 创建图像保存选项对象ImageSaveOptions options = new ImageSaveOptions(SaveFormat.JPEG);options.setPageCount(doc.getPageCount()); // 设置要转换的页数
//            options.setResolution(300); // 设置图像分辨率,默认为96dpi// 逐页转换并保存为图像for (int pageIndex = 0; pageIndex < doc.getPageCount(); pageIndex++) {String outputFileName = outputDir + "image_" + (pageIndex + 1) + ".png";options.setPageIndex(pageIndex);doc.save(outputFileName, options);}System.out.println("word2pdf共耗时:" + (System.currentTimeMillis() - old) / 1000.0 + "秒");} catch (Exception e) {e.printStackTrace();}}private static final byte[] LICENSE = ("<License>\n" +"    <Data>\n" +"        <Products>\n" +"            <Product>Aspose.Total for Java</Product>\n" +"            <Product>Aspose.Words for Java</Product>\n" +"        </Products>\n" +"        <EditionType>Enterprise</EditionType>\n" +"        <SubscriptionExpiry>20991231</SubscriptionExpiry>\n" +"        <LicenseExpiry>20991231</LicenseExpiry>\n" +"        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>\n" +"    </Data>\n" +"    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>\n" +"</License>").getBytes();/*** 判断是否有授权文件 如果没有则会认为是试用版,转换的文件会有水印*/public static void getLicense() {try (InputStream is = new ByteArrayInputStream(LICENSE)) {new License().setLicense(is);} catch (Exception e) {throw new RuntimeException(e);}}}
  • Aspose Jar 包下载
  • 参考文章《Java中几种office文档转pdf的方式》
  • 参考文章《Java开发中Word转PDF文件5种方案横向评测》

Apache ——iText 方案

<!-- POI Word2Pdf -->
<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>org.apache.poi.xwpf.converter.pdf</artifactId><version>1.0.6</version>
</dependency>

转换程序

import fr.opensagres.xdocreport.utils.StringUtils;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.*;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;/*** @author Rocca*/
public class WordPdfUtils {/*** 将word文档, 转换成pdf, 中间替换掉变量** @param source 源为word文档, 必须为docx文档* @param target 目标输出* @param params 需要替换的变量*/public static void wordConverterToPdf(InputStream source, OutputStream target, Map<String, String> params) {wordConverterToPdf(source, target, null, params);}/*** 将word文档, 转换成pdf, 中间替换掉变量** @param source  源为word文档, 必须为docx文档* @param target  目标输出* @param params  需要替换的变量* @param options PdfOptions.create().fontEncoding( "windows-1250" ) 或者其他*/public static void wordConverterToPdf(InputStream source, OutputStream target, PdfOptions options, Map<String, String> params) {long old = System.currentTimeMillis();try {XWPFDocument doc = new XWPFDocument(source);paragraphReplace(doc.getParagraphs(), params);for (XWPFTable table : doc.getTables()) {for (XWPFTableRow row : table.getRows()) {for (XWPFTableCell cell : row.getTableCells())paragraphReplace(cell.getParagraphs(), params);}}PdfConverter.getInstance().convert(doc, target, options);System.out.println("word2pdf共耗时:" + (System.currentTimeMillis() - old) / 1000.0 + "秒");} catch (IOException e) {throw new RuntimeException(e);}}/*** 替换段落中内容*/private static void paragraphReplace(List<XWPFParagraph> paragraphs, Map<String, String> params) {for (XWPFParagraph p : paragraphs) {for (XWPFRun r : p.getRuns()) {String content = r.getText(r.getTextPosition());if (StringUtils.isNotEmpty(content) && params.containsKey(content)) r.setText(params.get(content), 0);}}}}

PDF 转图片

上述的 Aspose.Word 并不支持 PDF 转图片。要使用 Aspose PDF 转图片须使用他家的另外一个产品 Aspose.Pdf。另外有趣的是,Aspose.Word 可以直接转为图片,但由于当前需求是得到了 Pdf 加盖章和签名之后转换图片的,并不能从 Word 直接转图片。而且感觉 Word 转图片也比较慢。

我感觉 PDF 转图片比较简单,不用 Aspose 也行,——于是使用了 Apache 的 Pdfbox。

<!-- PDF2Img -->
<dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.0</version>
</dependency>

你可以调整 DPI 分辨率,跟图片格式,下面例子是 gif 的。

/*** PDF 转图片** @param pdfFile PDF 文件*/
public static void pdf2Img(String pdfFile, String outputDir) {long old = System.currentTimeMillis();try (PDDocument document = Loader.loadPDF(new File(pdfFile))) {PDFRenderer renderer = new PDFRenderer(document);for (int i = 0; i < document.getNumberOfPages(); ++i) {ByteArrayOutputStream out = new ByteArrayOutputStream();ImageIO.write(renderer.renderImageWithDPI(i, DPI), "gif", out);// 将字节数组写入到文件try (FileOutputStream fos = new FileOutputStream(outputDir + FileHelper.SEPARATOR + "img-" + i + ".gif")) {fos.write(out.toByteArray());}}System.out.println("pdf2img共耗时:" + (System.currentTimeMillis() - old) / 1000.0 + "秒");} catch (IOException e) {e.printStackTrace();}
}

一般一份 PDF 是多页的,于是也会输出多张图片。所以你可以修改里面的文件名生成规则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/81854.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

100道基于Android毕业设计的选题题目,持续更新

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 大家好&#xff0c;我是程序员徐师兄、今天给大家谈谈基于android的app开发毕设题目&#xff0c;以及基于an…

深入理解Java单例模式和优化多线程任务处理

目录 饿汉模式懒汉模式单线程版多线程版双重检查锁定 阻塞队列 单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例&#xff0c;并提供一个全局访问点。 饿汉模式 类加载的同时&#xff0c;创建实例。 class Singleton {private static final Singlet…

运维自动化:提高效率的秘诀

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

GEE:快速实现NDVI时间序列NDVI线性趋势和变化敏感性计算(斜率、截距)

作者:CSDN @ _养乐多_ 本博客将向您介绍如何使用Google Earth Engine(GEE)平台来处理Landsat 5、7和8的卫星图像数据,计算NDVI的斜率和截距,以及如何导出这些结果供进一步分析使用。 文章目录 一、代码详解1.1 核心代码详解1.2 核心代码详解1.3 代码框架介绍二、完整代码…

day06_Java中的流程控制语句

流程控制 简单来讲所谓流程就是完成一件事情的多个步骤组合起来就叫做一个流程。在一个程序执行的过程中&#xff0c;各条语句的执行顺序对程序的结果是有直接影响的。我们必须清楚每条语句的执行流程。而且&#xff0c;很多时候要通过控制语句的执行顺序来实现我们想要的功能…

智慧公厕助力数字强市建设,打造善感知新型信息化公共厕所

随着城市建设的不断发展&#xff0c;智慧公厕作为一个重要的基础设施&#xff0c;正逐渐受到人们的重视。智慧公厕不仅为人们提供舒适的使用环境&#xff0c;更是通过数字化技术的应用&#xff0c;为城市发展注入新的动力。本文将以智慧公厕源头厂家广州中期科技有限公司&#…

@Validated 和 @Valid 的区别,你真的懂吗?SpringBoot 参数校验必知必会!

概述 Valid是使用Hibernate validation的时候使用Validated是只用Spring Validator校验机制使用 说明&#xff1a;java的JSR303声明了Valid这类接口&#xff0c;而Hibernate-validator对其进行了实现 Validation对Valid进行了二次封装&#xff0c;在使用上并没有区别&#xff…

Iterator设计模式

目录 1、示例 1.1 Aggregate接口 1.2 Iterator接口 1.3 Book类 1.4 BookShelf类 1.6 BookShelfIterator 类 1.7 Main类 2、解释Iterator模式中的角色 2.1 Iterator模式的存在意义 2.2 抽象类和接口 2.3 Aggregate 和 Iterator的对应 2.4 容易弄错"下一个"…

QT:使用多窗口做一个登录注册小项目(登录窗口、登录结果窗口、注册窗口)

widget.h(登录窗口) #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QCheckBox> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <Qmap> //模板类class Widget : public QWidget …

有效的括号(栈的高频面试题)

一、题目描述 题目连接&#xff1a;有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺…

005-第一代光电小工具(一)

第一代光电小工具(一) 文章目录 第一代光电小工具(一)项目介绍大致原理描述核心控件QCustomPlot关于QCustomPlot 播放音频软件截图 关键字&#xff1a; Qt、 Qml、 QCustomPlot、 曲线、 SQLite 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&…

MySQL修改时间添加时间自动更新

第一种: database.php设置 false改为true;然后看是使用的什么框架 如果是tp5需要数据库是create_time和update_time字段 laravel的话,需要的是created_at和updated_at字段 如果想自定义的话,就在model文件里加上 protected $createTime create_at;// 默认的字段为create_t…

LED智能家居灯 开关调光 台灯落地灯控制驱动 降压恒流IC AP5191

产品描述 AP5191是一款PWM工作模式,高效率、外围简单、内置功率MOS管&#xff0c;适用于4.5-150V输入的高精度降压LED恒流驱动芯片。输出最大功率150W&#xff0c;最大电流6A。AP5191可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5191 工作频率可以…

sketch for Mac快捷键大全

你可以在sketch中使用键盘快捷键来加快你的设计过程。要使用键盘快捷键&#xff0c;请同时按下下列列表的所有键。有些命令只能根据你在做什么或者你选择了什么才启用&#xff0c;所有把命令分成了下列不同的部分。 sketch下载地址&#xff1a;sketch 破解-Sketch for mac(专业…

# (1462. 课程表 IV leetcode)广搜+拓扑-------------------Java实现

&#xff08;1462. 课程表 IV leetcode&#xff09;广搜拓扑-------------------Java实现 题目表述 你总共需要上 numCourses 门课&#xff0c;课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite &#xff0c;其中 prerequisites[i] [ai, bi] 表示如果你想…

【Unity程序技巧】Unity中的单例模式的运用

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

iptables 防火墙配置

文章目录 iptables 防火墙配置规则链的分类–五链处理的动作iptables 常用参数和作用iptables 防火墙配置查看规则链清空规则链设置默认规则将流入的流量丢弃允许ICMP协议流量通过删除默认策略允许所以流量通过设置将所有流入22端口的流量全部拒绝允许指定网段的22端口通过设置…

selenium学习

selenium模块和爬虫之间的关联 便捷的获取网站中动态加载的数据便捷实现模拟登录 什么是selenium模块 基于浏览器自动化的一个模块 selenium使用流程&#xff1a; - 环境安装&#xff1a;pip install selenium - 下载一个浏览器的驱动程序&#xff08;谷歌浏览器&#xff…

【数据分享】2000-2022年全球范围500m分辨率类NPP-VIIRS夜间灯光数据

夜间灯光数据是我们在各项研究中经常使用的数据&#xff01;我们平时使用的夜间灯光数据主要来源于NPP/VIIRS和DMSP/OLS两种渠道&#xff0c;这两种数据由于分辨率、数据年份、传感器等不同存在不兼容的情况限制了长时序夜间灯光数据的使用&#xff0c;针对该问题我们之前分享过…

已解决 Kotlin Error: Type mismatch: inferred type is String but Int was expected

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…