openOffice word转pdf,pdf转图片优化版
之前写了一个版本的,不过代码繁琐而且不好用,效率有些问题。尤其pdf转图片速度太慢。下面是优化版本的代码。
spriing_boot 版本信息:2.0.1.RELEASE
1、配置信息:
package com.yunfatong.conf;import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.jodconverter.DocumentConverter; import org.jodconverter.LocalConverter; import org.jodconverter.office.LocalOfficeManager; import org.jodconverter.office.OfficeManager; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.HashSet; import java.util.Set;/*** openoffice 配置** @author liran* @date 20190517*/ @Configuration @ConditionalOnClass({DocumentConverter.class}) @ConditionalOnProperty(prefix = "jodconverter", name = {"enabled"}, havingValue = "true", matchIfMissing = true) @EnableConfigurationProperties({JodConverterProperties.class}) @Slf4j public class JodConverterAutoConfiguration {private final JodConverterProperties properties;public JodConverterAutoConfiguration(JodConverterProperties properties) {this.properties = properties;}private OfficeManager createOfficeManager() {LocalOfficeManager.Builder builder = LocalOfficeManager.builder();if (!StringUtils.isBlank(this.properties.getPortNumbers())) {Set<Integer> iports = new HashSet<>();String[] var3 = StringUtils.split(this.properties.getPortNumbers(), ", ");int var4 = var3.length;for (int var5 = 0; var5 < var4; ++var5) {String portNumber = var3[var5];iports.add(NumberUtils.toInt(portNumber, 2002));}builder.portNumbers(ArrayUtils.toPrimitive(iports.toArray(new Integer[iports.size()])));}builder.officeHome(this.properties.getOfficeHome());builder.workingDir(this.properties.getWorkingDir());builder.templateProfileDir(this.properties.getTemplateProfileDir());builder.killExistingProcess(this.properties.isKillExistingProcess());builder.processTimeout(this.properties.getProcessTimeout());builder.processRetryInterval(this.properties.getProcessRetryInterval());builder.taskExecutionTimeout(this.properties.getTaskExecutionTimeout());builder.maxTasksPerProcess(this.properties.getMaxTasksPerProcess());builder.taskQueueTimeout(this.properties.getTaskQueueTimeout());return builder.build();}@Bean(initMethod = "start", destroyMethod = "stop")@ConditionalOnMissingBeanpublic OfficeManager officeManager() {return this.createOfficeManager();}@Bean@ConditionalOnMissingBean@ConditionalOnBean({OfficeManager.class})public DocumentConverter jodConverter(OfficeManager officeManager) {return LocalConverter.make(officeManager);} }
package com.yunfatong.conf;import org.springframework.boot.context.properties.ConfigurationProperties;import java.util.regex.Pattern;/*** openoffice 配置** @author liran* @date 20190517*/ @ConfigurationProperties("jodconverter") public class JodConverterProperties {private boolean enabled;private String officeHome;private String portNumbers = "2002";private String workingDir;private String templateProfileDir;private boolean killExistingProcess = true;private long processTimeout = 120000L;private long processRetryInterval = 250L;private long taskExecutionTimeout = 120000L;private int maxTasksPerProcess = 200;private long taskQueueTimeout = 30000L;public JodConverterProperties() {}public boolean isEnabled() {return this.enabled;}public void setEnabled(boolean enabled) {this.enabled = enabled;}public String getOfficeHome() {//根据不同系统分别设置//office-home: C:\Program Files (x86)\OpenOffice 4 #windows下默认 不用修改// #office-home: /opt/openoffice4 #linux 默认 不用修改String osName = System.getProperty("os.name");if (Pattern.matches("Linux.*", osName)) {this.officeHome = "/opt/openoffice4";} else if (Pattern.matches("Windows.*", osName)) {this.officeHome = "C:\\Program Files (x86)\\OpenOffice 4";} else {this.officeHome = "/opt/openoffice4";}return this.officeHome;}public void setOfficeHome(String officeHome) {this.officeHome = officeHome;}public String getPortNumbers() {return this.portNumbers;}public void setPortNumbers(String portNumbers) {this.portNumbers = portNumbers;}public String getWorkingDir() {return this.workingDir;}public void setWorkingDir(String workingDir) {this.workingDir = workingDir;}public String getTemplateProfileDir() {return this.templateProfileDir;}public void setTemplateProfileDir(String templateProfileDir) {this.templateProfileDir = templateProfileDir;}public boolean isKillExistingProcess() {return this.killExistingProcess;}public void setKillExistingProcess(boolean killExistingProcess) {this.killExistingProcess = killExistingProcess;}public long getProcessTimeout() {return this.processTimeout;}public void setProcessTimeout(long processTimeout) {this.processTimeout = processTimeout;}public long getProcessRetryInterval() {return this.processRetryInterval;}public void setProcessRetryInterval(long procesRetryInterval) {this.processRetryInterval = procesRetryInterval;}public long getTaskExecutionTimeout() {return this.taskExecutionTimeout;}public void setTaskExecutionTimeout(long taskExecutionTimeout) {this.taskExecutionTimeout = taskExecutionTimeout;}public int getMaxTasksPerProcess() {return this.maxTasksPerProcess;}public void setMaxTasksPerProcess(int maxTasksPerProcess) {this.maxTasksPerProcess = maxTasksPerProcess;}public long getTaskQueueTimeout() {return this.taskQueueTimeout;}public void setTaskQueueTimeout(long taskQueueTimeout) {this.taskQueueTimeout = taskQueueTimeout;} }
application.yml
jodconverter:enabled: trueoffice-home: linuxOrwindows#/opt/openoffice4 #linux 默认 不用修改 C:\Program Files (x86)\OpenOffice 4 #windows下默认 不用修改port-numbers: 2002max-tasks-per-process: 10
2、转换入口
package com.yunfatong.ojd.util.pdf; import cn.hutool.core.date.DatePattern;import com.yunfatong.ojd.common.exception.CommonException;import com.yunfatong.ojd.service.FileSystemStorageService;import com.yunfatong.ojd.util.SpringUtil;import lombok.extern.slf4j.Slf4j;import org.apache.commons.io.FileUtils;import org.apache.commons.lang.StringUtils;import org.jodconverter.DocumentConverter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component; import java.io.File;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.util.ArrayList;import java.util.List; /** * word 转pdf * * @author lr */@Component@Slf4jpublic class TransferUtil { //这里没有@Autowired 主要是配置不启用的话 无法注入 private DocumentConverter documentConverter; @Autowired private FileSystemStorageService fileSystemStorageService; /** * fileSystemStorageService 就是拼接出本地路径的作用 * storage.winLocation=D:\\ojd\\upload\\images\\ * ##上传图片linux存储路径 * storage.linuxLocation=/home/ojd/upload/images/ */ final static String WORD_SUFFIX_DOC = "doc"; final static String WORD_SUFFIX_DOCX = "docx"; /** * word ->pdf * * @param webPath 浏览器可访问路径(数据库存的)如 /test/wd.word * @return 相同文件夹下的转换后的pdf 路径 如/test/wd_20190517151515333.pdf * @throws Exception */ public String transferWordToPdf(String webPath) throws Exception { if(documentConverter==null){ documentConverter = SpringUtil.getBean(DocumentConverter.class); } //转换成本地实际磁盘路径 String originLocalFilePath = fileSystemStorageService.getLocation(webPath); File inputFile = new File(originLocalFilePath); if (!inputFile.exists() || !inputFile.isFile() || (!StringUtils.contains(inputFile.getName(), WORD_SUFFIX_DOC) && !StringUtils.contains(inputFile.getName(), WORD_SUFFIX_DOCX))) { throw new CommonException("word -> pdf转换错误 当前文件不是word或 文件不存在: " + webPath); } DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_MS_PATTERN); String timeNow = formatter.format(LocalDateTime.now()); String newPdfWebPath = StringUtils.substringBeforeLast(webPath, ".") + "_" + timeNow + ".pdf"; try { File outputFile = new File(fileSystemStorageService.getLocation(newPdfWebPath)); documentConverter.convert(inputFile).to(outputFile).execute(); } catch (Exception e) { log.error("word->pdf 转换错误------------> Exception:{}", e); throw e; } return newPdfWebPath; } public List<String> transferPdfToImage(String webPath) throws Exception { String originLocalFilePath = fileSystemStorageService.getLocation(webPath); File inputFile = new File(originLocalFilePath); if (!inputFile.exists() || !inputFile.isFile() || webPath.lastIndexOf(".pdf") < 0) { throw new CommonException("pdf-> img 源文件不是pdf文件 或者文件不存在!" + webPath); } String localPdfpath = fileSystemStorageService.getLocation(webPath); String newImgWebPathPreSuffix = StringUtils.substringBeforeLast(webPath, "."); String localImgPath = fileSystemStorageService.getLocation(newImgWebPathPreSuffix); PdfTransferUtil pdfTranfer = new PdfTransferUtil(); List<byte[]> ins = pdfTranfer.pdf2Image(localPdfpath, "png", 1.5f); List<String> webPaths = new ArrayList<>(ins.size()); for (int i = 0; i < ins.size(); i++) { byte[] data = ins.get(i); String pathReal = localImgPath + "_ojd_" + i + ".png"; FileUtils.writeByteArrayToFile(new File(pathReal), data); webPaths.add(pathReal); } return webPaths; } }
pdf 转图片参考 https://gitee.com/cycmy/pdftranfer.git
package com.yunfatong.ojd.util.pdf;import lombok.extern.slf4j.Slf4j; import org.icepdf.core.pobjects.Document; import org.icepdf.core.pobjects.Page; import org.icepdf.core.util.GraphicsRenderingHints;import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;/*** @author lr* */ @Slf4j public class PdfTransferUtil {//*********************************pdf to image **********************************************************/*** 将指定pdf字节数组转换为指定格式图片二进制数组** @param pdfBytes PDF字节数组* @param imageType 转换图片格式 默认png* @param zoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%* @return List<byte [ ]>* @throws Exception*/public List<byte[]> pdf2Image(byte[] pdfBytes, String imageType, float zoom) throws Exception {Document document = new Document();document.setByteArray(pdfBytes, 0, pdfBytes.length, null);return pageExtraction(document, imageType, 0f, zoom);}/*** 将指定pdf输入流转换为指定格式图片二进制数组** @param inputPDF PDF二进制流* @param imageType 转换图片格式 默认png* @param zoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%* @return List<byte [ ]>* @throws Exception*/public List<byte[]> pdf2Image(InputStream inputPDF, String imageType, float zoom) throws Exception {Document document = new Document();document.setInputStream(inputPDF, null);return pageExtraction(document, imageType, 0f, zoom);}/*** 将指定pdf文件转换为指定格式图片二进制数组** @param pdfPath 原文件路径,例如d:/test.pdf* @param imageType 转换图片格式 默认png* @param zoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%* @return List<byte [ ]>* @throws Exception*/public List<byte[]> pdf2Image(String pdfPath, String imageType, float zoom) throws Exception {Document document = new Document();document.setFile(pdfPath);return pageExtraction(document, imageType, 0f, zoom);}//*********************************pdf to image **********************************************************private List<byte[]> pageExtraction(Document document, String imageType, float rotation, float zoom) {// setup two threads to handle image extraction.ExecutorService executorService = Executors.newFixedThreadPool(5);try {// create a list of callables.int pages = document.getNumberOfPages();List<byte[]> result = new ArrayList<byte[]>(pages);List<Callable<byte[]>> callables = new ArrayList<Callable<byte[]>>(pages);for (int i = 0; i < pages; i++) {callables.add(new CapturePage(document, i, imageType, rotation, zoom));}List<Future<byte[]>> listFuture = executorService.invokeAll(callables);executorService.submit(new DocumentCloser(document)).get();for (Future<byte[]> future : listFuture) {result.add(future.get());}return result;} catch (Exception ex) {log.error(" pdf 转换图片错误 Error handling PDF document " + ex);} finally {executorService.shutdown();}return null;}public class CapturePage implements Callable<byte[]> {private Document document;private int pageNumber;private String imageType;private float rotation;private float zoom;private CapturePage(Document document, int pageNumber, String imageType, float rotation, float zoom) {this.document = document;this.pageNumber = pageNumber;this.imageType = imageType;this.rotation = rotation;this.zoom = zoom;}@Overridepublic byte[] call() throws Exception {BufferedImage image = (BufferedImage) document.getPageImage(pageNumber, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, rotation, zoom);ByteArrayOutputStream bs = new ByteArrayOutputStream();ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);ImageIO.write(image, imageType, imOut);image.flush();return bs.toByteArray();}}/*** Disposes the document.*/public class DocumentCloser implements Callable<Void> {private Document document;private DocumentCloser(Document document) {this.document = document;}@Overridepublic Void call() {if (document != null) {document.dispose();log.info("Document disposed");}return null;}}}
springutils
package com.yunfatong.ojd.util;/*** @Auther liran* @Date 2018/8/30 14:49* @Description*/ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;@Component public class SpringUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if(SpringUtil.applicationContext == null) {SpringUtil.applicationContext = applicationContext;}System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name){return getApplicationContext().getBean(name);}//通过class获取Bean.public static <T> T getBean(Class<T> clazz){return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name,Class<T> clazz){return getApplicationContext().getBean(name, clazz);}}
pom.xml
<!--word转换pdf begin--><dependency><groupId>org.jodconverter</groupId><artifactId>jodconverter-core</artifactId><version>4.2.2</version></dependency><dependency><groupId>org.jodconverter</groupId><artifactId>jodconverter-local</artifactId><version>4.2.2</version></dependency><dependency><groupId>org.jodconverter</groupId><artifactId>jodconverter-spring-boot-starter</artifactId><version>4.2.2</version></dependency><!--word转换pdf end--><!--PDF转图片--><dependency><groupId>org.icepdf.os</groupId><artifactId>icepdf-core</artifactId><version>6.2.2</version><exclusions><exclusion><groupId>javax.media</groupId><artifactId>jai_core</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.icepdf.os</groupId><artifactId>icepdf-viewer</artifactId><version>6.2.2</version></dependency><!--PDF转图片 end-->
3、调用测试:
import com.yunfatong.ojd.service.FileSystemStorageService; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;import java.util.List;@RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class WordTransferPdfUtilTest {@AutowiredTransferUtil wordTransferPdfUtil;@AutowiredFileSystemStorageService fileSystemStorageService;@Testpublic void transferLocalFile() {
try { /*******************word 转pdf******************/ long time = System.currentTimeMillis(); System.out.println("start :======" + time); wordTransferPdfUtil.transferWordToPdf("courtChongqing/test_new/555.docx"); log.error(System.currentTimeMillis() + " time============================== :" + ((System.currentTimeMillis() - time) / 1000)); /*******************pdf转图片******************/ long time2 = System.currentTimeMillis(); List<String> pdfImages2 = wordTransferPdfUtil.transferPdfToImage("courtChongqing/test_new/333.pdf"); for (String pdfImage : pdfImages2) { log.error(pdfImage); } log.error(" time===============================22222222 :" + ((System.currentTimeMillis() - time2) / 1000));// System.out.println("pdf path =============" + path); } catch (Exception e) { e.printStackTrace(); }
} }
转载于:https://www.cnblogs.com/liran123/p/10883582.html
openOffice word转pdf,pdf转图片优化版相关推荐
- linux打开word乱码,解决linux下openoffice word文件转PDF中文乱码的问题
网上很多介绍是由于jdk中的没有字体导致乱码,而我遇到的是转换过程并未报错,但转换后的PDF中是乱码,尝试在jre/lib/fonts/中增加字体,还是不能解决问题,因此可以判断非jre字体问题,是l ...
- word转PDF,PDF转图片
PDF转图片 最近公司业务需求将pdf,和word文件转成图片.在网上找了很多,也测试了很多.最终根据自己的需求做成了下面两个工具类,来完成需求.pdf转图片用的是icepdf,可以自己根据需求添加水 ...
- Python从Word/PPT/PDF中抽取图片
Python从Word/PPT/PDF中抽取图片 PS 1:也是从网上各个帖子中学习的代码,因此代码的格式以及内容有粘贴网上其他大神的代码,如有侵权请告知删除 2:本次设计意在用pyinstaller ...
- 解决word转PDF文件时图片位置改变和字体格式改变的问题
解决word转PDF文件时图片位置改变和字体格式改变的问题 在写论文的时候,使用word编辑完文本后将其导出为PDF总是出现图片位置改变或者字体格式改变的问题,好不容易在word中编辑好的格式却不能在 ...
- 【Java】SpringBoot后端格式转换:把Word转成PDF再按页转成图片在前端展示(Linux)
ConvertUtil 1. word2pdf 1.1 aspose-word插件 1.2 word转pdf 1.2.1 添加license文件 1.2.2 具体实现 2. pdf2imgByPage ...
- word转pdf时,图片错位,乱跑
参考:word转pdf时,图片错位 问题: 在word通过另存为转换pdf时,经常出现图片错误的现象,如何解决呢? 方法: 点word-文件-打印-adobe pdf-另存为-桌面,通过这方法打印出的 ...
- word转换成pdf,包括导航目录和图片不变黑
1.word转换成pdf,包括导航目录和图片不变黑: 有些时候将word转换成pdf,我们会发现生成的文件要么不带导航目录,要么就是图片显示有问题,比如变黑.变黑是因为某些图片在作图时修改了透明度,因 ...
- Typora基础用法:pandoc安装,导入导出word文档,pdf文件。设置图片目录
点击观看B站视频 Typora基础用法:pandoc安装,导入导出word文档,pdf文件.设置图片目录. 一. pandoc安装 首次安装完typora,是没法导入的,需要安装pandoc 选择[请 ...
- Word批量转PDF(内容转图片,防复制文字)
一.软件下载地址 Word批量转PDF(内容转图片,防复制文字)(2021-07-13更新)下载地址: https://download.csdn.net/download/techinged/241 ...
最新文章
- php 优化sql,php – 优化此SQL查询
- 构建具有用户身份认证的 React + Flux 应用程序
- 日期格式化的“疑难杂症”
- [导入]php 安全基础 附录C. 加密
- Elasticsearch调优实践
- Linux 免密登录配置
- python opencv 实现从一个文件夹中读取图片做切割处理后放入另一个文件夹
- python和nodejs数据传递_python中的*和**参数传递机制
- [我总结]8月第二周总结
- 2020年php发卡源码,2020年最新PHP自动化售货发卡网源码带教程安装
- CM/CMR/CMP防火等级有何区别?CM/CMR/CMP级电缆网线如何选?
- h3c交换机重启_h3c交换机清空配置命令
- ZoomIt使用教程
- 使用Pinyin4Swift进行汉字拼音转换
- 飞桨PaddlePaddle 英特尔神经计算棒 联合优化AI算法CPU部署性能,推动产业低成本智能化升级
- 接口返回本站点必须要开启JavaScript才能运行的解决方案
- 怎样夸学计算机的人,学学古人是怎样夸人有才的
- Kubernetes网络插件flannel和calico
- UE4 坐标转换 之 CAD 坐标转UE
- RSYNC 自动同步文件免密
热门文章
- Ceph mon节点故障处理案例分解
- [转]总不能一辈子做助理
- Makefile中指示符“include”、“-include”和“sinclude”的区别
- pollepoll实现分析(二)——epoll实现
- Exchange2013公用文件夹
- “私有云”安全的“过渡”时期-“云朵”方案的设计思路
- jsp常见获取地址函数之间的不同
- 如何在java中叠加图层
- iOS10 推送必看 UNNotificationContentExtension
- error C2065: “IDD_DIALOG1”: 未声明的标识符