Java Word 转 PDF和图片
基于Libreoffice进行转化的,其他的要么付费,要么转化起来格式错误
Windows
https://zh-cn.libreoffice.org/download/libreoffice/?type=win-x86_64&version=7.5.1&lang=zh-CN
去官网下载就可以了,再把对应的安装C:\Program Files\LibreOffice\program\配置到环境变量Path中,就可以试试了
--查看版本
soffice --version
--进行转化
soffice --headless --invisible --convert-to pdf:writer_pdf_Export H:/这里是你的文件名.docx --outdir H:/
Linux
官网地址:https://zh-cn.libreoffice.org/ 去下载对应版本的安装包
yum remove libreoffice-*
-- yum无法使用,可以参考 https://blog.csdn.net/weixin_48205084/article/details/135340920?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-135340920-blog-132372521.235^v43^pc_blog_bottom_relevance_base4&spm=1001.2101.3001.4242.2&utm_relevant_index=2
tar -zxvf LibreOffice_7.5.1_Linux_x86-64_rpm.tar.gz
cd /LibreOffice_7.0.3_Linux_x86-64_rpm/RPMS
yum localinstall *.rpm
安装libreoffice-headless(安装这个东西,需要java环境,可以先安装一下java环境)
yum install libreoffice-headless
soffice --headless --invisible --convert-to pdf name.doc
Docker镜像
# 使用 openjdk:8-jdk-alpine 作为基础镜像
FROM openjdk:8-jdk-alpine
# 设置环境变量以避免交互提示
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN:zh
ENV LC_ALL zh_CN.UTF-8
# 安装必要的软件包和中文字体
RUN apk update && apk add --no-cache \
wget \
bash \
fontconfig \
ttf-dejavu \
&& apk add --no-cache --virtual .build-deps \
msttcorefonts-installer \
&& update-ms-fonts \
&& fc-cache -f \
&& apk del .build-deps
# 下载并安装LibreOffice
RUN wget https://download.documentfoundation.org/libreoffice/stable/7.6.7/rpm/x86_64/LibreOffice_7.6.7_Linux_x86-64_rpm.tar.gz && \
mkdir -p /opt/libreoffice && \
tar -xzf LibreOffice_7.6.7_Linux_x86-64_rpm.tar.gz -C /opt/libreoffice --strip-components=1 && \
rm LibreOffice_7.6.7_Linux_x86-64_rpm.tar.gz
# 将LibreOffice添加到PATH中
ENV PATH="/opt/libreoffice/program:${PATH}"
# 设置工作目录
WORKDIR /workspace
# 设置默认命令行
CMD ["/bin/bash"]
Java中使用
直接复制该工具类就可以了
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
package com.lzc.util;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 依赖libreoffice实现PDF转化
*
*/
@Component
public class PdfUtils {
/**
* @param filePath 原文件路径 本地路径
* @param targetFolder 目标文件夹
*/
@Async
public void toPdf(String filePath, String targetFolder) {
long start = System.currentTimeMillis();
String srcPath = filePath, desPath = targetFolder;
System.out.println("源文件:" + filePath);
System.out.println("目标文件夹:" + targetFolder);
String command = "";
String osName = System.getProperty("os.name");
System.out.println("系统名称:" + osName);
if (osName.contains("Windows")) {
command = "soffice --headless --convert-to pdf " + srcPath + " --outdir " + desPath;
System.out.println(command);
windowExec(command);
} else {
command = "soffice --headless --invisible --convert-to pdf " + srcPath + " --outdir "+ desPath;
LinuxExec(command);
}
long end = System.currentTimeMillis();
System.out.println("转换文件耗时:" + (end - start) + "毫秒");
}
private boolean windowExec(String command) {
Process process;// Process可以控制该子进程的执行或获取该子进程的信息
try {
process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。
} catch (IOException e) {
System.out.println("异常了:" + e);
return false;
}
int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值,返回0表示正常结束
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
if (i != 0) {
System.out.println("异常了:" + i);
windowExec(command);
}
} catch (InterruptedException e) {
return false;
}
process.destroy(); // 销毁子进程
process = null;
return true;
}
private void LinuxExec(String cmd) {
System.out.println(cmd);
try {
Process process = Runtime.getRuntime().exec(cmd);
int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值,返回0表示正常结束
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
if (i != 0) {
System.out.println("异常了:" + i);
LinuxExec(cmd);
}
} catch (InterruptedException e) {
System.err.println(e.getMessage());
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
/***
* PDF文件转PNG图片,全部页数
*
* @param PdfFilePath pdf文件路径 物理路径
* @param dstImgFolder 图片存放的文件夹
* @param dpi dpi越大转换后越清晰,相对转换速度越慢 dpi为96,100,105,120,150,200中,105显示效果较为清晰,体积稳定,dpi越高图片体积越大,一般电脑显示分辨率为96
* @return
*/
public int pdf2Image(String PdfFilePath, String dstImgFolder, int dpi) {
int pages = 1;
PDDocument pdDocument;
try {
File file = new File(PdfFilePath);
while (!file.exists()) {
System.out.println("文件未生成,等待1秒");
Thread.sleep(1000);
}
pdDocument = PDDocument.load(file);
int dot = PdfFilePath.lastIndexOf('.');
int lastSep = PdfFilePath.lastIndexOf(File.separator) + 1;
String imagePDFName = PdfFilePath.substring(lastSep, dot); // 获取图片文件名
PDFRenderer renderer = new PDFRenderer(pdDocument);
/* dpi越大转换后越清晰,相对转换速度越慢 */
pages = pdDocument.getNumberOfPages();
StringBuffer imgFilePath = null;
for (int i = 0; i < pages; i++) {
String imgFilePathPrefix = dstImgFolder + File.separator + imagePDFName;
imgFilePath = new StringBuffer();
imgFilePath.append(imgFilePathPrefix);
imgFilePath.append("_");
imgFilePath.append(String.valueOf(i + 1));
imgFilePath.append(".png");
File dstFile = new File(imgFilePath.toString());
BufferedImage image = renderer.renderImageWithDPI(i, dpi);
ImageIO.write(image, "png", dstFile);
}
System.out.println("PDF文档转PNG图片成功!");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return pages;
}
}