gitee java pdf转图片_openOffice word转pdf,pdf转图片优化版

这是一个关于使用Java和openOffice优化PDF转图片和word转pdf的博客。博主分享了如何配置openOffice,以及使用JodConverter库进行转换。文章中提供了详细的配置代码,并展示了如何在Spring Boot应用中集成和使用这些转换工具。
摘要由CSDN通过智能技术生成

之前写了一个版本的,不过代码繁琐而且不好用,效率有些问题。尤其pdf转图片速度太慢。下面是优化版本的代码。

spriing_boot 版本信息:2.0.1.RELEASE

1、配置信息:

packagecom.yunfatong.conf;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.lang3.ArrayUtils;importorg.apache.commons.lang3.StringUtils;importorg.apache.commons.lang3.math.NumberUtils;importorg.jodconverter.DocumentConverter;importorg.jodconverter.LocalConverter;importorg.jodconverter.office.LocalOfficeManager;importorg.jodconverter.office.OfficeManager;importorg.springframework.boot.autoconfigure.condition.ConditionalOnBean;importorg.springframework.boot.autoconfigure.condition.ConditionalOnClass;importorg.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;importorg.springframework.boot.autoconfigure.condition.ConditionalOnProperty;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.HashSet;importjava.util.Set;/*** openoffice 配置

*

*@authorliran

* @date 20190517*/@Configuration

@ConditionalOnClass({DocumentConverter.class})

@ConditionalOnProperty(prefix= "jodconverter", name = {"enabled"}, havingValue = "true", matchIfMissing = true)

@EnableConfigurationProperties({JodConverterProperties.class})

@Slf4jpublic classJodConverterAutoConfiguration {private finalJodConverterProperties properties;publicJodConverterAutoConfiguration(JodConverterProperties properties) {this.properties =properties;

}privateOfficeManager createOfficeManager() {

LocalOfficeManager.Builder builder=LocalOfficeManager.builder();if (!StringUtils.isBlank(this.properties.getPortNumbers())) {

Set 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(newInteger[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());returnbuilder.build();

}

@Bean(initMethod= "start", destroyMethod = "stop")

@ConditionalOnMissingBeanpublicOfficeManager officeManager() {return this.createOfficeManager();

}

@Bean

@ConditionalOnMissingBean

@ConditionalOnBean({OfficeManager.class})publicDocumentConverter jodConverter(OfficeManager officeManager) {returnLocalConverter.make(officeManager);

}

}

packagecom.yunfatong.conf;importorg.springframework.boot.context.properties.ConfigurationProperties;importjava.util.regex.Pattern;/*** openoffice 配置

*

*@authorliran

* @date 20190517*/@ConfigurationProperties("jodconverter")public classJodConverterProperties {private booleanenabled;privateString officeHome;private String portNumbers = "2002";privateString workingDir;privateString 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;publicJodConverterProperties() {

}public booleanisEnabled() {return this.enabled;

}public void setEnabled(booleanenabled) {this.enabled =enabled;

}publicString 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 voidsetOfficeHome(String officeHome) {this.officeHome =officeHome;

}publicString getPortNumbers() {return this.portNumbers;

}public voidsetPortNumbers(String portNumbers) {this.portNumbers =portNumbers;

}publicString getWorkingDir() {return this.workingDir;

}public voidsetWorkingDir(String workingDir) {this.workingDir =workingDir;

}publicString getTemplateProfileDir() {return this.templateProfileDir;

}public voidsetTemplateProfileDir(String templateProfileDir) {this.templateProfileDir =templateProfileDir;

}public booleanisKillExistingProcess() {return this.killExistingProcess;

}public void setKillExistingProcess(booleankillExistingProcess) {this.killExistingProcess =killExistingProcess;

}public longgetProcessTimeout() {return this.processTimeout;

}public void setProcessTimeout(longprocessTimeout) {this.processTimeout =processTimeout;

}public longgetProcessRetryInterval() {return this.processRetryInterval;

}public void setProcessRetryInterval(longprocesRetryInterval) {this.processRetryInterval =procesRetryInterval;

}public longgetTaskExecutionTimeout() {return this.taskExecutionTimeout;

}public void setTaskExecutionTimeout(longtaskExecutionTimeout) {this.taskExecutionTimeout =taskExecutionTimeout;

}public intgetMaxTasksPerProcess() {return this.maxTasksPerProcess;

}public void setMaxTasksPerProcess(intmaxTasksPerProcess) {this.maxTasksPerProcess =maxTasksPerProcess;

}public longgetTaskQueueTimeout() {return this.taskQueueTimeout;

}public void setTaskQueueTimeout(longtaskQueueTimeout) {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

@Slf4j

public class TransferUtil {

[email protected] 主要是配置不启用的话 无法注入

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 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 ins = pdfTranfer.pdf2Image(localPdfpath, "png", 1.5f);

List 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

packagecom.yunfatong.ojd.util.pdf;importlombok.extern.slf4j.Slf4j;importorg.icepdf.core.pobjects.Document;importorg.icepdf.core.pobjects.Page;importorg.icepdf.core.util.GraphicsRenderingHints;importjavax.imageio.ImageIO;importjavax.imageio.stream.ImageOutputStream;importjava.awt.image.BufferedImage;importjava.io.ByteArrayOutputStream;importjava.io.InputStream;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.Future;/***@authorlr

* //原文:https://blog.csdn.net/qq_35974759/article/details/83149734

*/@Slf4jpublic classPdfTransferUtil {//*********************************pdf to image **********************************************************

/*** 将指定pdf字节数组转换为指定格式图片二进制数组

*

*@parampdfBytes PDF字节数组

*@paramimageType 转换图片格式 默认png

*@paramzoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%

*@returnList

*@throwsException*/

public List pdf2Image(byte[] pdfBytes, String imageType, float zoom) throwsException {

Document document= newDocument();

document.setByteArray(pdfBytes,0, pdfBytes.length, null);returnpageExtraction(document, imageType, 0f, zoom);

}/*** 将指定pdf输入流转换为指定格式图片二进制数组

*

*@paraminputPDF PDF二进制流

*@paramimageType 转换图片格式 默认png

*@paramzoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%

*@returnList

*@throwsException*/

public List pdf2Image(InputStream inputPDF, String imageType, float zoom) throwsException {

Document document= newDocument();

document.setInputStream(inputPDF,null);returnpageExtraction(document, imageType, 0f, zoom);

}/*** 将指定pdf文件转换为指定格式图片二进制数组

*

*@parampdfPath 原文件路径,例如d:/test.pdf

*@paramimageType 转换图片格式 默认png

*@paramzoom 缩略图显示倍数,1表示不缩放,0.3则缩小到30%

*@returnList

*@throwsException*/

public List pdf2Image(String pdfPath, String imageType, float zoom) throwsException {

Document document= newDocument();

document.setFile(pdfPath);returnpageExtraction(document, imageType, 0f, zoom);

}//*********************************pdf to image **********************************************************

private List pageExtraction(Document document, String imageType, float rotation, floatzoom) {//setup two threads to handle image extraction.

ExecutorService executorService = Executors.newFixedThreadPool(5);try{//create a list of callables.

int pages =document.getNumberOfPages();

List result = new ArrayList(pages);

List> callables = new ArrayList>(pages);for (int i = 0; i < pages; i++) {

callables.add(newCapturePage(document, i, imageType, rotation, zoom));

}

List> listFuture =executorService.invokeAll(callables);

executorService.submit(newDocumentCloser(document)).get();for (Futurefuture : listFuture) {

result.add(future.get());

}returnresult;

}catch(Exception ex) {

log.error(" pdf 转换图片错误 Error handling PDF document " +ex);

}finally{

executorService.shutdown();

}return null;

}public class CapturePage implements Callable{privateDocument document;private intpageNumber;privateString imageType;private floatrotation;private floatzoom;private CapturePage(Document document, int pageNumber, String imageType, float rotation, floatzoom) {this.document =document;this.pageNumber =pageNumber;this.imageType =imageType;this.rotation =rotation;this.zoom =zoom;

}

@Overridepublic byte[] call() throwsException {

BufferedImage image=(BufferedImage) document.getPageImage(pageNumber, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, rotation, zoom);

ByteArrayOutputStream bs= newByteArrayOutputStream();

ImageOutputStream imOut=ImageIO.createImageOutputStream(bs);

ImageIO.write(image, imageType, imOut);

image.flush();returnbs.toByteArray();

}

}/*** Disposes the document.*/

public class DocumentCloser implements Callable{privateDocument document;privateDocumentCloser(Document document) {this.document =document;

}

@OverridepublicVoid call() {if (document != null) {

document.dispose();

log.info("Document disposed");

}return null;

}

}

}

springutils

packagecom.yunfatong.ojd.util;/*** @Auther liran

* @Date 2018/8/30 14:49

* @Description*/

importorg.springframework.beans.BeansException;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;importorg.springframework.stereotype.Component;

@Componentpublic class SpringUtil implementsApplicationContextAware {private staticApplicationContext applicationContext;

@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throwsBeansException {if(SpringUtil.applicationContext == null) {

SpringUtil.applicationContext=applicationContext;

}

System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");

}//获取applicationContext

public staticApplicationContext getApplicationContext() {returnapplicationContext;

}//通过name获取 Bean.

public staticObject getBean(String name){returngetApplicationContext().getBean(name);

}//通过class获取Bean.

public static T getBean(Classclazz){returngetApplicationContext().getBean(clazz);

}//通过name,以及Clazz返回指定的Bean

public static T getBean(String name,Classclazz){returngetApplicationContext().getBean(name, clazz);

}

}

pom.xml

org.jodconverter

jodconverter-core

4.2.2

org.jodconverter

jodconverter-local

4.2.2

org.jodconverter

jodconverter-spring-boot-starter

4.2.2

org.icepdf.os

icepdf-core

6.2.2

javax.media

jai_core

org.icepdf.os

icepdf-viewer

6.2.2

3、调用测试:

importcom.yunfatong.ojd.service.FileSystemStorageService;importlombok.extern.slf4j.Slf4j;importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.test.context.junit4.SpringRunner;importjava.util.List;

@RunWith(SpringRunner.class)

@SpringBootTest

@Slf4jpublic classWordTransferPdfUtilTest {

@Autowired

TransferUtil wordTransferPdfUtil;

@Autowired

FileSystemStorageService fileSystemStorageService;

@Testpublic voidtransferLocalFile() {

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 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值