java后端实现将office转pdf功能,主要用于前端页面展示;
代码实现(libreOffice实现 + office实现):
libreOffice实现:
java实现逻辑:
import javax.annotation.Resource;
public class FileHandler1 {
@Resource
private DocumentConverter documentConverter;
/**
* 文件转换
* @param filepath
* @return
* @throws OfficeException
*/
@PostMapping("qwe")
public String toPdf() throws OfficeException {
long l = System.currentTimeMillis();
log.info("++++++++++++++++++++++++++++++++++" + l);
String filepath = "E:\\能源.docx";
File word = new File("E:\\能源.docx");
//截取字符串把word的后缀改为pdf
String pdfpath= filepath.substring(0,filepath.lastIndexOf("."))+".pdf";
File pdf = new File(pdfpath);
//文件转换
documentConverter.convert(word).to(pdf).execute();
return (l - System.currentTimeMillis()) + "";
}
}
application.yml
jodconverter:
local:
enabled: true
# 设置LibreOffice主目录
office-home: D:/allSoltware/LibreOffice/install2
# 开启多个LibreOffice进程,每个端口对应一个进程
portNumbers: 8100,8101,8102
# LibreOffice进程重启前的最大进程数
maxTasksPerProcess: 100
pom.xml
<!-- word转pdf所需jar begin -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-spring-boot-starter</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>ridl</artifactId>
<version>5.4.2</version>
</dependency>
<!-- word转pdf所需jar end -->
注:这种实现方式转换时间很快,但是对于格式问题会有偏移,错位等影响
office实现:
java实现逻辑1(这个可以):
package energy.controller;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import java.io.File;
import org.springframework.stereotype.Component;
/**
* @author
* @date 2020/9/27
*/
@Component
public class Jacob {
/** 转PDF格式值 */
static final int WORD_FORMAT_PDF = 17;
static final int EXCEL_FORMAT_PDF = 0;
static final int PPT_FORMAT_PDF = 32;
/*** @Description:根据文件类型转换为pdf */
public void convert2PDF(String inputFile, String pdfFile) {
String suffix = getFileSufix(inputFile);
if (suffix.equals("doc") || suffix.equals("docx") || suffix.equals("txt")) {
word2PDF(inputFile, pdfFile);
} else if (suffix.equals("xls") || suffix.equals("xlsx")) {
excel2PDF(inputFile, pdfFile);
} else if (suffix.equals("ppt") || suffix.equals("pptx")) {
ppt2PDF(inputFile, pdfFile);
} else {
System.out.println("文件格式不支持转换!");
}
}
/** * @Description:word转pdf */
private void word2PDF(String inputFile, String pdfFile) {
System.out.println("启动Word...");
long start = System.currentTimeMillis();
ActiveXComponent app = null;
Dispatch doc = null;
try {
// 创建一个word对象
app = new ActiveXComponent("Word.Application");
// 不可见打开word (但默认是不可见的)
app.setProperty("Visible", new Variant(false));
// 获取文挡属性
// 调用Documents对象中Open方法打开文档,并返回打开的文档对象Document
Dispatch docs = app.getProperty("Documents").toDispatch();
doc = Dispatch.call(docs, "Open", inputFile).toDispatch();
System.out.println("打开文档..." + inputFile);
System.out.println("转换文档到PDF..." + pdfFile);
File tofile = new File(pdfFile);
if(tofile.exists()) {
tofile.delete();
}
// word保存为pdf格式宏,值为17
Dispatch.call(doc, "SaveAs", pdfFile, WORD_FORMAT_PDF);
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
} finally {
Dispatch.call(doc, "Close", false);
System.out.println("关闭文档");
if (app != null) {
app.invoke("Quit", new Variant[]{});
}
}
//如果没有这句话,winword.exe进程将不会关闭
ComThread.Release();
}
/** * @Description:excel转pdf */
private void excel2PDF(String inputFile, String pdfFile) {
System.out.println("启动Excel...");
long start = System.currentTimeMillis();
ActiveXComponent app = null;
Dispatch excel = null;
try {
// 创建一个excel对象
app = new ActiveXComponent("Excel.Application");
// 不可见打开excel
app.setProperty("Visible", new Variant(false));
// 获取文挡属性
Dispatch excels = app.getProperty("Workbooks").toDispatch();
// 调用Documents对象中Open方法打开文档,并返回打开的文档对象Document
excel = Dispatch.call(excels, "Open", inputFile).toDispatch();
System.out.println("打开文档..." + inputFile);
System.out.println("转换文档到PDF..." + pdfFile);
File tofile = new File(pdfFile);
if(tofile.exists()) {
tofile.delete();
}
// Excel不能调用SaveAs方法
Dispatch.call(excel, "ExportAsFixedFormat", EXCEL_FORMAT_PDF, pdfFile);
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
} finally {
Dispatch.call(excel, "Close", false);
System.out.println("关闭文档");
if (app != null) {
app.invoke("Quit", new Variant[]{});
}
}
//如果没有这句话,winword.exe进程将不会关闭
ComThread.Release();
}
/*** @Description:ppt转pdf */
private void ppt2PDF(String inputFile, String pdfFile) {
System.out.println("启动PPT...");
long start = System.currentTimeMillis();
ActiveXComponent app = null;
Dispatch ppt = null;
try {
// 创建一个ppt对象
app = new ActiveXComponent("PowerPoint.Application");
// 不可见打开(PPT转换不运行隐藏,所以这里要注释掉)
// app.setProperty("Visible", new Variant(false));
// 获取文挡属性
Dispatch ppts = app.getProperty("Presentations").toDispatch();
// 调用Documents对象中Open方法打开文档,并返回打开的文档对象Document
ppt = Dispatch.call(ppts, "Open", inputFile, true, true, false).toDispatch();
System.out.println("打开文档..." + inputFile);
System.out.println("转换文档到PDF..." + pdfFile);
File tofile = new File(pdfFile);
if(tofile.exists()) {
tofile.delete();
}
Dispatch.call(ppt, "SaveAs", pdfFile, PPT_FORMAT_PDF);
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
} finally {
Dispatch.call(ppt, "Close");
System.out.println("关闭文档");
if (app != null) {
app.invoke("Quit", new Variant[]{});
}
}
//如果没有这句话,winword.exe进程将不会关闭
ComThread.Release();
}
/*** @Description:获取文件后缀*/
private String getFileSufix(String fileName) {
int splitIndex = fileName.lastIndexOf(".");
return fileName.substring(splitIndex + 1);
}
}
java实现逻辑2(这个也可以):
package energy.controller;
import java.io.File;
import com.google.common.base.Objects;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.springframework.stereotype.Component;
@Component
public class PdfUtil {
/**
* 将word/excel/ppt转成pdf
* Title: WPSToPdf
* Description:
* @param wpsPath
* @return
*/
public String WPSToPdf(String wpsPath){
boolean flag = false;
String pdfPath = null;
File file = new File(wpsPath);
if (file.exists()) {
if (wpsPath.startsWith("/")) {
wpsPath = wpsPath.substring(1);
wpsPath = wpsPath.replace("/", "\\");
}
pdfPath = wpsPath.substring(0, wpsPath.lastIndexOf("."))+".pdf";
String fileType = wpsPath.substring(wpsPath.lastIndexOf(".")+1);
if (Objects.equal(fileType, "docx") || Objects.equal(fileType, "doc")) {
flag = wordToPdf(wpsPath, pdfPath);
}else if (Objects.equal(fileType, "xlsx") || Objects.equal(fileType, "xls")) {
flag = excelToPdf(wpsPath, pdfPath);
}else if (Objects.equal(fileType, "pptx") || Objects.equal(fileType, "ppt")) {
flag = pptToPdf(wpsPath, pdfPath);
}
}
if (flag) {
return pdfPath;
}
return null;
}
/**
* 将word文档转换为pdf文件
* Title: wordToPdf
* Description:
* @param wordPath
* @param pdfPath
* @return
*/
public boolean wordToPdf(String wordPath,String pdfPath){
ActiveXComponent component = new ActiveXComponent("Word.Application");
try {
component.setProperty("Visible", false);
Dispatch dispatch = component.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.call(dispatch, "Open",new Object[]{wordPath,false,true}).toDispatch();
Dispatch.call(doc, "ExportAsFixedFormat",new Object[]{pdfPath,17});
Dispatch.call(doc, "Close", new Object[]{false});
component.invoke("Quit",0);
return true;
} catch (Exception e) {
e.printStackTrace();
component.invoke("Quit",0);
return false;
}
}
/**
* 将excel文件转换为pdf文件
* Title: excelToPdf
* Description:
* @param excelPath
* @param pdfPath
* @return
*/
public boolean excelToPdf(String excelPath,String pdfPath){
ComThread.InitSTA(true);
ActiveXComponent component = new ActiveXComponent("Excel.Application");
try {
component.setProperty("Visible", false);
component.setProperty("AutomationSecurity", new Variant(3));
Dispatch dispatch = component.getProperty("Workbooks").toDispatch();
Dispatch doc = Dispatch.invoke(dispatch,"Open",1,
new Object[]{excelPath,new Variant(false),new Variant(false)},new int[9]).toDispatch();
Dispatch.invoke(doc, "ExportAsFixedFormat", 1, new Object[]{new Variant(0),pdfPath,new Variant(0)}, new int[1]);
Dispatch.call(doc,"close", new Object[]{false});
if (component != null) {
component.invoke("Quit",new Variant[0]);
component = null;
}
ComThread.Release();
return true;
} catch (Exception e) {
e.printStackTrace();
component.invoke("Quit");
return false;
}
}
/**
* ppt文件转pdf文件
* Title: pptToPdf
* Description:
* @param pptPath
* @param pdfPath
* @return
*/
public boolean pptToPdf(String pptPath,String pdfPath){
ActiveXComponent component = new ActiveXComponent("Powerpoint.Application");
try {
Dispatch ppts = component.getProperty("Presentations").toDispatch();
Dispatch ppt = Dispatch.call(ppts, "Open", new Object[]{pptPath,true,true,false}).toDispatch();
Dispatch.call(ppt, "SaveAs",new Object[]{pdfPath,32});
Dispatch.call(ppt,"Close");
component.invoke("Quit");
return true;
} catch (Exception e) {
e.printStackTrace();
component.invoke("Quit");
return false;
}
}
}
pom.xml
<dependency>
<groupId>com.java</groupId>
<artifactId>example-app</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/repo/jacob.jar</systemPath>
</dependency>
需要将jar包放入项目中
还需要将jacob-1.19-x64.dll这个文件放入jdk的bin目录下,不然会报初始化失败的错误!
注:采用office的话需要安装office办公,速度要慢一些,但是还原度高,从事商业的话,可能会存在购买使用权的问题