代码可直接测试运行,我这里JDK17,Maven3.5,IDEA2023
业务需求
我们现有业务是通过poi来实现内容转word,以及各类电子签名和图片,平时相关人员是将word下载下来,然后盖章扫描,再传回平台。 现在需求是在特殊情况下,需要特殊处理,不走这个流程了,因为太麻烦,所以想再平台上直接生成盖章后的pdf,直接使用。
其实需求很简单,就是要最终盖好章的pdf,发给客户,好,那我们就开始吧。
选用技术
我大概了解了下,常用的主要就是下面几种方式
•使用Aspose.Words库:Aspose.Words是一个功能强大的库,支持将Word文档转换为PDF格式。你需要将Aspose.Words的许可证字符串设置到你的程序中,然后使用相应的API进行转换。
•使用documents4j库:对于Windows环境,documents4j库可以在有Microsoft Office服务的情况下将Word文档转换为PDF。这需要安装Microsoft Office,并且可能需要在程序中配置Office的路径。
•使用LibreOffice服务:在Linux环境下,可以利用LibreOffice服务将Word文档转换为PDF。这需要在服务器上安装LibreOffice,并且可能需要在程序中配置LibreOffice的路径。
•使用Apache POI和iText库:这种方法适用于处理.doc和.docx格式的Word文档。首先使用Apache POI读取Word文档的内容,然后使用iText库将内容转换为PDF格式。这种方法可能需要处理Word文档中的复杂格式和布局。 使用其他第三方库:例如Spire.Doc库,它提供了一个简单的API来将Word文档转换为PDF格式。你可以通过下载jar包或使用Maven仓库安装导入这个库。
•使用OpenOffice服务:如果你的环境中安装了OpenOffice,你可以使用Java调用OpenOffice的服务来将Word文档转换为PDF。这需要在Java程序中配置OpenOffice的路径和服务设置。
权衡之下,我选择了Aspose.Words,其实选择OpenOffice效果最好,以后等我有空了,会选择这种方式实现,到时候再分享。
实现逻辑
导入依赖,由于Aspose.Words在私服仓库,所以直接pom是无法导入的,需要将jar包手动传到maven仓库,然后在pom引入
去官网下载jar包[1],记得选择21.6的jar包
<dependency>
<groupId>
com.aspose
</groupId>
<artifactId>
aspose-words
</artifactId>
<version>
21.6
</version>
<classifier>
jdk17
</classifier>
</dependency>
<dependency>
<groupId>
com.itextpdf
</groupId>
<artifactId>
itext-asian
</artifactId>
<version>
5.2.0
</version>
</dependency>
<dependency>
<groupId>
com.itextpdf
</groupId>
<artifactId>
itextpdf
</artifactId>
<version>
5.5.13
</version>
</dependency>
<dependency>
<groupId>
com.itextpdf.tool
</groupId>
<artifactId>
xmlworker
</artifactId>
<version>
5.5.13
</version>
</dependency>
建议使用21.6版本,这个版本我去了水印(正版需要购买证书),相当于破解了吧,其它版本暂未尝试。
其实就是两个文件,WordPdfUtil.java和ImageUtil
WordPdfUtil.java
package
com
.
manxin
.
ltd
.
datacenter
.
util
;
import
com
.
aspose
.
words
.
Document
;
import
com
.
aspose
.
words
.
SaveFormat
;
import
com
.
itextpdf
.
text
.
Image
;
import
com
.
itextpdf
.
text
.
.
PdfReader
;
import
com
.
itextpdf
.
text
.
.
PdfStamper
;
import
javax
.
imageio
.
ImageIO
;
import
java
.
awt
.
image
.
BufferedImage
;
import
java
.
io
.*;
import
java
.
lang
.
reflect
.
Modifier
;
public
class
WordToPdfUtils
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Document
doc
=
null
;
//去水印
Class
<?>
aClass
=
Class
.
forName
(
"com.aspose.words.zzXyu"
);
java
.
lang
.
reflect
.
Field
zzZXG
=
aClass
.
getDeclaredField
(
"zzZXG"
);
zzZXG
.
setAccessible
(
true
);
java
.
lang
.
reflect
.
Field
modifiersField
=
zzZXG
.
getClass
().
getDeclaredField
(
"modifiers"
);
modifiersField
.
setAccessible
(
true
);
modifiersField
.
setInt
(
zzZXG
,
zzZXG
.
getModifiers
()
&
~
Modifier
.
FINAL
);
zzZXG
.
set
(
null
,
new
byte
[]{
76
,
73
,
67
,
69
,
78
,
83
,
69
,
68
});
try
{
String
resultPath
=
"E:\download\test\test"
+
".pdf"
;
FileOutputStream
os
=
new
FileOutputStream
(
resultPath
);
doc
=
new
Document
(
new
FileInputStream
(
"E:\download\test\test.docx"
));
doc
.
save
(
os
,
SaveFormat
.
);
//添加印章
FileInputStream
pdfIs
=
new
FileInputStream
(
"E:\download\test\test.pdf"
);
// 1.1 读取模板文件
PdfReader
reader
=
new
PdfReader
(
pdfIs
);
// 1.2 创建文件输出流
FileOutputStream
out
=
new
FileOutputStream
(
"E:\download\test\testnew.pdf"
);
// 2、创建PdfStamper对象
PdfStamper
stamper
=
new
PdfStamper
(
reader
,
out
);
// 4、读取公章
String
path
=
"E:\download\test\baogao.png"
;
BufferedImage
bufferedImage
=
ImageIO
.
read
(
new
FileInputStream
(
path
));
BufferedImage
[]
imgs
=
ImageUtil
.
splitImage
(
bufferedImage
,
1
,
2
);
// 5、读公章图片
Image
image
=
Image
.
getInstance
(
ImageUtil
.
imageToBytes
(
bufferedImage
));
// 公章大小,x轴
int
chunkWidth
=
150
;
// 公章大小,y轴
int
chunkHeight
=
150
;
// pdf页面页码
int
pdfPages
=
reader
.
getNumberOfPages
();
// 6.3 最后一页盖公章
image
.
scaleToFit
(
chunkWidth
,
chunkHeight
);
//得到的位置有些许偏差,自行调节
image
.
setAbsolutePosition
(
380
,
310
);
stamper
.
getOverContent
(
pdfPages
).
addImage
(
image
);
stamper
.
close
();
out
.
close
();
reader
.
close
();
pdfIs
.
close
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
ImageUtil.java
package
com
.
whohs
.
smartmsp
.
opscenter
.
util
;
import
javax
.
imageio
.
ImageIO
;
import
java
.
awt
.*;
import
java
.
awt
.
image
.
BufferedImage
;
import
java
.
io
.
ByteArrayOutputStream
;
import
java
.
io
.
IOException
;
public
class
ImageUtil
{
/**
*
@Description
:分割图片
*
@Date
:
2024
/
06
/
10
*
@Param
image
:
图片
BufferedImage
流
*
@Param
rows
:
分割行
*
@Param
cols
:
分割列
*
@return
:
java
.
awt
.
image
.
BufferedImage
[]
返回分割后的图片流
**/
public
static
BufferedImage
[]
splitImage
(
BufferedImage
image
,
int
rows
,
int
cols
)
{
// 分割成4*4(16)个小图
int
chunks
=
rows
*
cols
;
// 计算每个小图的宽度和高度
int
chunkWidth
=
image
.
getWidth
()
/
cols
+
3
;
// 向右移动3
int
chunkHeight
=
image
.
getHeight
()
/
rows
;
int
count
=
0
;
BufferedImage
[]
imgs
=
new
BufferedImage
[
chunks
];
for
(
int
x
=
0
;
x
<
rows
;
x
++)
{
for
(
int
y
=
0
;
y
<
cols
;
y
++)
{
//设置小图的大小和类型
imgs
[
count
]
=
new
BufferedImage
(
chunkWidth
,
chunkHeight
,
BufferedImage
.
TYPE_INT_RGB
);
//写入图像内容
Graphics2D
gr
=
imgs
[
count
].
createGraphics
();
// 增加下面代码使得背景透明
imgs
[
count
]
=
gr
.
getDeviceConfiguration
().
createCompatibleImage
(
chunkWidth
,
chunkHeight
,
Transparency
.
TRANSLUCENT
);
gr
.
dispose
();
gr
=
imgs
[
count
].
createGraphics
();
gr
.
drawImage
(
image
,
0
,
0
,
chunkWidth
,
chunkHeight
,
chunkWidth
*
y
,
chunkHeight
*
x
,
chunkWidth
*
y
+
chunkWidth
,
chunkHeight
*
x
+
chunkHeight
,
null
);
gr
.
dispose
();
count
++;
}
}
return
imgs
;
}
/**
*
@Description
:
将
BufferedImage
转换成字节数组
*
@Date
:2024/06/10
*
@Param
bufferedImage
:
*
@return
:
byte
[]
**/
public
static
byte
[]
imageToBytes
(
BufferedImage
bufferedImage
)
throws
IOException
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ImageIO
.
write
(
bufferedImage
,
"png"
,
baos
);
baos
.
flush
();
byte
[]
imageInByte
=
baos
.
toByteArray
();
baos
.
close
();
return
imageInByte
;
}
}
代码就不解释了,几乎都有注释,大家一看就清楚了,有此类需求的可以做为参考。
上一条:aspose插件费用
下一条:Aspose Email 的功能
品质保证
多年的生产力软件专家
专业实力
资深技术支持项目实施团队
安全无忧
多位认证安全工程师
多元服务
软件提供方案整合,项目咨询实施
购软平台-找企业级软件,上购软平台。平台提供更齐全的软件产品、更专业的技术服务,同时提供行业资讯、软件使用教程和技巧。购软平台打造企业级数字产品综合应用服务平台。用户体验和数字类产品的专业化服务是我们不断追求的目标。购软平台您身边的企业级数字产品优秀服务商。