Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-oss
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xingmin
yd-oss
Commits
6021871e
Commit
6021871e
authored
Oct 19, 2025
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
push
parent
86bf98c2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
146 additions
and
23 deletions
+146
-23
yd-oss-service/src/main/java/com/yd/oss/service/service/impl/PdfServiceImpl.java
+41
-0
yd-oss-service/src/main/java/com/yd/oss/service/utils/PdfUtil.java
+105
-23
No files found.
yd-oss-service/src/main/java/com/yd/oss/service/service/impl/PdfServiceImpl.java
View file @
6021871e
...
@@ -132,6 +132,17 @@ public class PdfServiceImpl<T> implements PdfService<T> {
...
@@ -132,6 +132,17 @@ public class PdfServiceImpl<T> implements PdfService<T> {
// 获取当前系统名称
// 获取当前系统名称
String
osName
=
System
.
getProperty
(
"os.name"
).
toLowerCase
();
String
osName
=
System
.
getProperty
(
"os.name"
).
toLowerCase
();
log
.
info
(
"开始PDF转换 - 源文件: {}, 目标文件: {}, 系统: {}"
,
wordFile
.
getAbsolutePath
(),
pdfFile
.
getAbsolutePath
(),
osName
);
// 记录源文件内容信息用于调试
try
{
String
sourceContentPreview
=
getWordContentPreview
(
wordFile
);
log
.
info
(
"源文件内容预览: {}"
,
sourceContentPreview
);
}
catch
(
Exception
e
)
{
log
.
warn
(
"无法获取源文件内容预览: {}"
,
e
.
getMessage
());
}
if
(
osName
.
contains
(
"win"
))
{
if
(
osName
.
contains
(
"win"
))
{
// Windows系统
// Windows系统
PdfUtil
.
winWordToPdf
(
pdfFile
,
wordFile
);
PdfUtil
.
winWordToPdf
(
pdfFile
,
wordFile
);
...
@@ -141,6 +152,36 @@ public class PdfServiceImpl<T> implements PdfService<T> {
...
@@ -141,6 +152,36 @@ public class PdfServiceImpl<T> implements PdfService<T> {
}
else
{
}
else
{
throw
new
UnsupportedOperationException
(
"Unsupported operating system: "
+
osName
);
throw
new
UnsupportedOperationException
(
"Unsupported operating system: "
+
osName
);
}
}
// 验证转换结果
if
(
pdfFile
.
exists
()
&&
pdfFile
.
length
()
>
0
)
{
log
.
info
(
"PDF转换成功! 文件: {}, 大小: {} bytes"
,
pdfFile
.
getAbsolutePath
(),
pdfFile
.
length
());
}
else
{
throw
new
RuntimeException
(
"PDF转换失败,目标文件不存在或为空: "
+
pdfFile
.
getAbsolutePath
());
}
}
/**
* 获取Word文件内容预览(用于调试)
*/
private
String
getWordContentPreview
(
File
wordFile
)
throws
IOException
{
try
(
XWPFDocument
doc
=
new
XWPFDocument
(
new
FileInputStream
(
wordFile
)))
{
StringBuilder
content
=
new
StringBuilder
();
// 获取前3个段落的前100个字符
int
paragraphCount
=
0
;
for
(
XWPFParagraph
p
:
doc
.
getParagraphs
())
{
if
(
paragraphCount
>=
3
)
break
;
String
text
=
p
.
getText
();
if
(
text
!=
null
&&
!
text
.
trim
().
isEmpty
())
{
content
.
append
(
text
.
substring
(
0
,
Math
.
min
(
text
.
length
(),
100
))).
append
(
"... "
);
paragraphCount
++;
}
}
return
content
.
toString
();
}
}
}
/**
/**
...
...
yd-oss-service/src/main/java/com/yd/oss/service/utils/PdfUtil.java
View file @
6021871e
...
@@ -7,6 +7,8 @@ import lombok.extern.slf4j.Slf4j;
...
@@ -7,6 +7,8 @@ import lombok.extern.slf4j.Slf4j;
import
java.io.*
;
import
java.io.*
;
import
java.nio.file.Files
;
import
java.nio.file.Files
;
import
java.nio.file.StandardCopyOption
;
import
java.nio.file.StandardCopyOption
;
import
java.util.Arrays
;
import
java.util.Date
;
@Slf4j
@Slf4j
public
class
PdfUtil
{
public
class
PdfUtil
{
...
@@ -51,6 +53,13 @@ public class PdfUtil {
...
@@ -51,6 +53,13 @@ public class PdfUtil {
// 确保输出目录存在
// 确保输出目录存在
new
File
(
outDir
).
mkdirs
();
new
File
(
outDir
).
mkdirs
();
// 根据源文件名预测LibreOffice的输出文件名
String
sourceFileName
=
wordFile
.
getName
();
String
expectedPdfName
=
sourceFileName
.
substring
(
0
,
sourceFileName
.
lastIndexOf
(
'.'
))
+
".pdf"
;
File
expectedPdfFile
=
new
File
(
outDir
,
expectedPdfName
);
log
.
info
(
"预期LibreOffice输出文件: {}"
,
expectedPdfFile
.
getAbsolutePath
());
// 使用绝对路径尝试不同的命令
// 使用绝对路径尝试不同的命令
String
[]
commands
=
{
String
[]
commands
=
{
"/usr/bin/libreoffice --invisible --headless --convert-to pdf --outdir "
+
outDir
+
" "
+
sourcePath
,
"/usr/bin/libreoffice --invisible --headless --convert-to pdf --outdir "
+
outDir
+
" "
+
sourcePath
,
...
@@ -66,39 +75,61 @@ public class PdfUtil {
...
@@ -66,39 +75,61 @@ public class PdfUtil {
for
(
String
command
:
commands
)
{
for
(
String
command
:
commands
)
{
try
{
try
{
log
.
info
(
"尝试命令: {}"
,
command
);
log
.
info
(
"尝试命令: {}"
,
command
);
// 清理可能存在的预期PDF文件(避免使用旧文件)
if
(
expectedPdfFile
.
exists
())
{
log
.
warn
(
"删除已存在的预期PDF文件: {}"
,
expectedPdfFile
.
getAbsolutePath
());
expectedPdfFile
.
delete
();
}
String
output
=
executeLinuxCmdWithOutput
(
command
);
String
output
=
executeLinuxCmdWithOutput
(
command
);
log
.
info
(
"命令输出: {}"
,
output
);
log
.
info
(
"命令输出: {}"
,
output
);
// 等待一下让文件生成
// 等待文件生成,使用更可靠的等待机制
Thread
.
sleep
(
2000
);
if
(
waitForPdfFile
(
expectedPdfFile
,
10
))
{
// 检查PDF文件是否生成
if
(
expectedPdfFile
.
exists
()
&&
expectedPdfFile
.
length
()
>
0
)
{
log
.
info
(
"LibreOffice生成PDF成功! 文件: {}, 大小: {} bytes, 使用命令: {}"
,
expectedPdfFile
.
getAbsolutePath
(),
expectedPdfFile
.
length
(),
command
);
// 检查PDF文件是否生成
// 复制到目标位置
if
(
pdfFile
.
exists
()
&&
pdfFile
.
length
()
>
0
)
{
Files
.
copy
(
expectedPdfFile
.
toPath
(),
pdfFile
.
toPath
(),
StandardCopyOption
.
REPLACE_EXISTING
);
log
.
info
(
"PDF转换成功! 文件: {}, 大小: {} bytes, 使用命令: {}"
,
log
.
info
(
"成功复制PDF到目标位置: {}, 大小: {} bytes"
,
pdfFile
.
getAbsolutePath
(),
pdfFile
.
length
(),
command
);
pdfFile
.
getAbsolutePath
(),
pdfFile
.
length
());
success
=
true
;
success
=
true
;
break
;
break
;
}
}
else
{
}
else
{
log
.
warn
(
"命令执行成功但未生成
目标
PDF文件: {}"
,
command
);
log
.
warn
(
"命令执行成功但未生成
预期
PDF文件: {}"
,
command
);
// 检查输出目录中是否有其他PDF文件(
LibreOffice可能使用不同的命名
)
// 检查输出目录中是否有其他PDF文件(
按修改时间排序,取最新的
)
File
outDirFile
=
new
File
(
outDir
);
File
outDirFile
=
new
File
(
outDir
);
File
[]
pdfFiles
=
outDirFile
.
listFiles
((
dir
,
name
)
->
name
.
toLowerCase
().
endsWith
(
".pdf"
));
File
[]
pdfFiles
=
outDirFile
.
listFiles
((
dir
,
name
)
->
name
.
toLowerCase
().
endsWith
(
".pdf"
)
&&
!
name
.
equals
(
pdfFile
.
getName
()));
// 排除目标文件本身
if
(
pdfFiles
!=
null
&&
pdfFiles
.
length
>
0
)
{
if
(
pdfFiles
!=
null
&&
pdfFiles
.
length
>
0
)
{
log
.
info
(
"在输出目录中找到以下PDF文件:"
);
// 按最后修改时间排序,取最新的PDF文件
Arrays
.
sort
(
pdfFiles
,
(
f1
,
f2
)
->
Long
.
compare
(
f2
.
lastModified
(),
f1
.
lastModified
()));
log
.
info
(
"在输出目录中找到 {} 个PDF文件,按修改时间排序:"
,
pdfFiles
.
length
);
for
(
File
f
:
pdfFiles
)
{
for
(
File
f
:
pdfFiles
)
{
log
.
info
(
" - {} (大小: {} bytes)"
,
f
.
getName
(),
f
.
length
());
log
.
info
(
" - {} (大小: {} bytes, 修改时间: {})"
,
// 如果找到PDF文件,复制到目标位置
f
.
getName
(),
f
.
length
(),
new
Date
(
f
.
lastModified
()));
if
(
f
.
length
()
>
0
)
{
}
Files
.
copy
(
f
.
toPath
(),
pdfFile
.
toPath
(),
StandardCopyOption
.
REPLACE_EXISTING
);
if
(
pdfFile
.
exists
()
&&
pdfFile
.
length
()
>
0
)
{
// 使用最新的PDF文件
log
.
info
(
"已复制PDF文件到目标位置: {}"
,
pdfFile
.
getAbsolutePath
());
File
latestPdf
=
pdfFiles
[
0
];
success
=
true
;
if
(
latestPdf
.
length
()
>
0
)
{
break
;
log
.
info
(
"使用最新的PDF文件: {}"
,
latestPdf
.
getAbsolutePath
());
}
Files
.
copy
(
latestPdf
.
toPath
(),
pdfFile
.
toPath
(),
StandardCopyOption
.
REPLACE_EXISTING
);
if
(
pdfFile
.
exists
()
&&
pdfFile
.
length
()
>
0
)
{
log
.
info
(
"已复制PDF文件到目标位置: {}"
,
pdfFile
.
getAbsolutePath
());
success
=
true
;
break
;
}
}
}
}
if
(
success
)
break
;
}
else
{
}
else
{
log
.
warn
(
"输出目录中未找到任何PDF文件"
);
log
.
warn
(
"输出目录中未找到任何PDF文件"
);
}
}
...
@@ -109,12 +140,62 @@ public class PdfUtil {
...
@@ -109,12 +140,62 @@ public class PdfUtil {
}
}
}
}
// 清理临时文件
try
{
if
(
expectedPdfFile
.
exists
())
{
expectedPdfFile
.
delete
();
log
.
info
(
"清理临时PDF文件: {}"
,
expectedPdfFile
.
getAbsolutePath
());
}
}
catch
(
Exception
e
)
{
log
.
warn
(
"清理临时文件失败: {}"
,
e
.
getMessage
());
}
if
(!
success
)
{
if
(!
success
)
{
throw
new
RuntimeException
(
"所有LibreOffice转换命令都失败,源文件: "
+
sourcePath
,
lastException
);
throw
new
RuntimeException
(
"所有LibreOffice转换命令都失败,源文件: "
+
sourcePath
,
lastException
);
}
}
}
}
/**
/**
* 等待PDF文件生成
*/
private
static
boolean
waitForPdfFile
(
File
pdfFile
,
int
maxWaitSeconds
)
{
log
.
info
(
"等待PDF文件生成: {}, 最大等待时间: {}秒"
,
pdfFile
.
getAbsolutePath
(),
maxWaitSeconds
);
for
(
int
i
=
0
;
i
<
maxWaitSeconds
*
2
;
i
++)
{
if
(
pdfFile
.
exists
())
{
long
fileSize
=
pdfFile
.
length
();
log
.
info
(
"检测到PDF文件存在,当前大小: {} bytes"
,
fileSize
);
if
(
fileSize
>
0
)
{
// 确保文件已经完全写入
long
size1
=
pdfFile
.
length
();
try
{
Thread
.
sleep
(
500
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
return
false
;
}
long
size2
=
pdfFile
.
length
();
if
(
size1
==
size2
&&
size1
>
0
)
{
log
.
info
(
"PDF文件已稳定,最终大小: {} bytes"
,
size1
);
return
true
;
}
}
}
try
{
Thread
.
sleep
(
500
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
break
;
}
}
log
.
warn
(
"等待PDF文件生成超时,文件存在: {}, 文件大小: {} bytes"
,
pdfFile
.
exists
(),
pdfFile
.
exists
()
?
pdfFile
.
length
()
:
0
);
return
false
;
}
/**
* 执行命令行并返回输出
* 执行命令行并返回输出
*/
*/
private
static
String
executeLinuxCmdWithOutput
(
String
cmd
)
throws
Exception
{
private
static
String
executeLinuxCmdWithOutput
(
String
cmd
)
throws
Exception
{
...
@@ -187,4 +268,4 @@ public class PdfUtil {
...
@@ -187,4 +268,4 @@ public class PdfUtil {
PdfUtil
.
linuxWordToPdf
(
pdfFile
,
wordFile
);
PdfUtil
.
linuxWordToPdf
(
pdfFile
,
wordFile
);
}
}
}
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment