当前位置: 首页 > news >正文

word文档转pdf开源免费,可自定义水印

在 Spring Boot 中实现 Word 转 PDF 并保留格式、添加水印,主流方案有POI+ITextAspose.WordsOpenOffice/LibreOffice三种,其中Aspose.Words在格式保留和水印功能上综合效果最优,其次是 OpenOffice/LibreOffice,POI+IText 适合轻量且开源优先的场景。

word文档转pdf,有几种方案。

1、Aspose.Words,免费的有水印,商业,处理能力最强,格式最好

2、**LibreOffice,开源,java调用,中高格式,**依赖外部服务部署,多实例并发需额外配置,水印需二次处理

3、POI+IText(开源,轻量场景)通过 Apache POI 读取 Word 内容,再用 IText 生成 PDF,格式需手动映射(如字体、段落、表格),水印通过 IText 添加,非常复杂。

采用第二种方案,开源免费,效果还可以。

1、首先下载:LibreOffice_25.8.2_Win_x86-64.msi 下载地址:https://zh-cn.libreoffice.org/download/libreoffice/

2、安装,默认安装即可

linux安装:

# Ubuntu/Debian
sudo apt-get update && sudo apt-get install libreoffice libreoffice-headless# CentOS
sudo yum install libreoffice libreoffice-headless

linux安装中文字体:

# Ubuntu/Debian
sudo apt-get install fonts-wqy-microhei fonts-wqy-zenhei# CentOS
sudo yum install fontconfig
sudo yum install wqy-microhei-fonts # 或手动上传 Windows 字体到 /usr/share/fonts/chinese/

3、启动libreoffice服务,cmd切换到安装目录下,服务端口8100

windows启动:

C:\Program Files\LibreOffice\program>soffice.exe  --headless --invisible --nologo --nodefault --nofirststartwizard --accept="socket,host=0.0.0.0,port=8100;urp

linux启动:

# 启动服务并监听 8100 端口
soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard &# 验证服务是否启动
netstat -tlnp | grep 8100  # 应显示 soffice.bin 进程

4、maven依赖

<dependencies><!-- JODConverter:连接 LibreOffice 服务 --><dependency><groupId>org.jodconverter</groupId><artifactId>jodconverter-core</artifactId><version>4.4.6</version></dependency><dependency><groupId>org.jodconverter</groupId><artifactId>jodconverter-local</artifactId><version>4.4.6</version> <!-- 本地服务用这个 --><!-- 远程服务需替换为:jodconverter-remote --></dependency><!-- iText:PDF 加水印 --><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version> <!-- 支持中文 --></dependency>
</dependencies>

5、java代码

package cn.myproject.watermark;import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.local.LocalConverter;
import org.jodconverter.local.office.LocalOfficeManager;import java.io.*;
import java.nio.file.Files;public class WordToPdfMain {// LibreOffice 服务地址和端口(根据实际部署修改)private static final String OFFICE_HOST = "127.0.0.1"; // 本地服务用127.0.0.1,远程用服务器IPprivate static final int OFFICE_PORT = 8100;public static void main(String[] args) {// 输入输出文件路径(根据实际文件修改)String inputWordPath = "D://tmp/test.doc";  // 源Word文件String outputPdfPath = "D://tmp//result.pdf"; // 目标PDF文件String watermarkText = "内部文档-禁止外传"; // 水印文字// 1. 启动Office管理器(连接LibreOffice服务)LocalOfficeManager officeManager = LocalOfficeManager.builder()
//                .host(OFFICE_HOST).portNumbers(OFFICE_PORT).build();try {officeManager.start();System.out.println("LibreOffice服务连接成功!");// 2. 创建转换器DocumentConverter converter = LocalConverter.builder().officeManager(officeManager).build();// 3. 转换并添加水印convertWordToPdfWithWatermark(converter,new File(inputWordPath),new File(outputPdfPath),watermarkText);System.out.println("转换完成!PDF路径:" + outputPdfPath);} catch (Exception e) {System.err.println("转换失败:" + e.getMessage());e.printStackTrace();} finally {// 4. 停止服务(释放资源)try {if (officeManager != null) {officeManager.stop();}} catch (Exception e) {e.printStackTrace();}}}/*** Word转PDF并添加水印*/private static void convertWordToPdfWithWatermark(DocumentConverter converter,File inputWord,File outputPdf,String watermarkText) throws Exception {// 创建临时PDF文件(无水印)File tempPdf = Files.createTempFile("temp-", ".pdf").toFile();try {// 第一步:Word转临时PDFconverter.convert(inputWord).to(tempPdf).execute();// 第二步:给临时PDF加水印,输出到目标文件addWatermark(tempPdf, outputPdf, watermarkText);} finally {// 删除临时文件if (tempPdf.exists() && !tempPdf.delete()) {System.out.println("临时文件删除失败:" + tempPdf.getAbsolutePath());}}}/*** 给PDF添加文字水印*/private static void addWatermark(File inputPdf, File outputPdf, String watermarkText) throws Exception {PdfReader reader = new PdfReader(new FileInputStream(inputPdf));PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));// 设置中文字体BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);// 遍历所有页添加水印int totalPages = reader.getNumberOfPages();for (int i = 1; i <= totalPages; i++) {PdfContentByte content = stamper.getUnderContent(i); // 水印在文字下方content.beginText();content.setFontAndSize(baseFont, 36); // 水印大小content.setColorFill(BaseColor.LIGHT_GRAY); // 水印颜色
//            content.setAlphaStroke(0.3f); // 透明度// 计算居中位置并倾斜45度Rectangle pageSize = reader.getPageSize(i);float x = pageSize.getWidth() / 2;float y = pageSize.getHeight() / 2;content.showTextAligned(Element.ALIGN_CENTER, watermarkText, x, y, -45);content.endText();}// 关闭资源stamper.close();reader.close();}
}

6、同时支持远程调用

在配置远程调用前,需确保两个基础条件:

  1. 服务监听外部地址:LibreOffice 服务启动时,必须将host参数设为0.0.0.0(而非127.0.0.1),允许所有网卡接收请求。
  2. 网络端口开放:服务所在服务器的防火墙(如 Linux 的iptables、Windows 防火墙)、云服务器安全组需开放监听端口(如 8100)。

windows下:

# 远程可访问的启动命令(端口8100)
"D:\Program Files\LibreOffice\program\soffice.exe" --headless --invisible --nologo --nodefault --nofirststartwizard --accept="socket,host=0.0.0.0,port=8100;urp;"

linux下:将启动命令中的host=127.0.0.1改为host=0.0.0.0,示例:

# 远程可访问的启动命令(端口8100)
soffice --headless --accept="socket,host=0.0.0.0,port=8100;urp;" --nofirststartwizard &# 验证监听地址(应显示 0.0.0.0:8100,而非 127.0.0.1:8100)
netstat -tlnp | grep 8100

四、并发处理与性能优化

1. 多端口扩展(Linux/Windows)

bash

# 启动多个服务实例(端口 8100-8102)
soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;" &
soffice --headless --accept="socket,host=127.0.0.1,port=8101;urp;" &
soffice --headless --accept="socket,host=127.0.0.1,port=8102;urp;" &
2. JODConverter 配置(Spring Boot)

yaml

jodconverter:local:enabled: truekill-existing-process: truemax-tasks-per-process: 100  # 每个进程最大任务数office-home: /usr/lib/libreoffice  # Linux 路径# office-home: D:\Program Files\LibreOffice  # Windows 路径port-numbers: 8100,8101,8102  # 多端口负载均衡
http://www.dtcms.com/a/486138.html

相关文章:

  • k8s(五)PV和PVC详解
  • 深度学习与自然语言处理
  • python 部署可离线使用的中文识别OCR(window)
  • 湖州微信网站建设网站301了不知道在哪做的
  • 请描述网站开发的一般流程图php网站开发经理招聘
  • 关于pkg-config的使用示例--g++编译过程引入第三方库(如Opencv、Qt)
  • 外贸soho先做网站wordpress如何把背景颜色调为白色
  • zk02-知识演进
  • 全自动相机在线标定方法
  • 设计模式篇之 中介者模式 Mediator
  • 卫星几何处理
  • 【个人成长笔记】在Ubuntu中的Linux系统安装sogoupinyin搜狗输入法完整版(亲测有效)
  • 3d驱动模型。如何让人物说话?什么情况下需要训练wav2lip模型,自己训练的好处是什么?操作步骤是?
  • 画册什么网站做方便做外汇著名网站
  • CRMEB标准版PHP订单发货全解析
  • Flink 窗口 Join 与区间 Join 实战详解
  • 分布式监控体系:从指标采集到智能告警的完整之道
  • 《Muduo网络库:实现one loop per thread设计模式》
  • 怎么注册网站卖东西哪有培训网站开发
  • makefile概述
  • 用R处理nc文件
  • GaussDB DN动态内存使用满导致DN主备切换
  • 湖南微网站开发北京市建设规划网站
  • TCP与UDP:传输层双雄的核心对比
  • 安化网站建设怎样建个人网站 步骤
  • 并查集-547.省份的数量-力扣(LeetCode)
  • 生命周期全景图:从componentDidMount到getSnapshotBeforeUpdate
  • p2p做网站plc编程入门基础知识
  • 学院个人信息|基于SprinBoot+vue的学院个人信息管理系统(源码+数据库+文档)
  • Unity AB包加载与依赖管理全解析