背景
因为本来用的是POI,调研了一些POI的api,虽然有一些获取总页数的方法,但是一旦word里有图片获得的总页数就不准确了。
看有大牛提到过用转pdf的方法来获取word总页数,但是只适用于windows平台下,但我们甲方的服务器是Linux的,所以才采用了另一款转pdf的工具–Libreoffice
解决方法
1.对于没有图片的word,可以尝试调用下代码:
参考:https://stackoverflow/questions/2848514/number-of-pages-in-a-word-doc-in-java
String lowerFilePath = filePath.toLowerCase();
if (lowerFilePath.endsWith(".docx")) {
XWPFDocument docx = new XWPFDocument(POIXMLDocument.openPackage(lowerFilePath));
return docx.getProperties().getExtendedProperties().getUnderlyingProperties().getPages();
} else if (lowerFilePath.endsWith(".doc")) {
HWPFDocument wordDoc = new HWPFDocument(new FileInputStream(lowerFilePath));
return wordDoc.getSummaryInformation().getPageCount();
}
2.对于有图片的word,可以先把它转换成pdf,
3.然后再读取pdf的页数
局限性
不得不说,利用这个工具将word转化成pdf后,pdf中换行符的高度要比word中的换行符的高度要高。也就是说,如果word中的有一个换行符在一页的最后面,那么很有可能在pdf中这个换行符就要移到了下一页去。
这就导致了会多出空白页。
我目前是让文档里不要有太多的换行符,感觉我也不知道该怎么做了
准备工作
需要先安装Libreoffice这个软件,因为利用它,可以用java代码来控制word转pdf,且格式良好
1.安装libreoffice(linux还需要装unoconv),windows到官网下载安装包,linux直接用命令行装即可:
https://zh-cn.libreoffice/get-help/install-howto/linux/(linux版及libreoffice中文官网)
linux下:
(1)sudo apt install libreoffice
(2)linux还需要安装unoconv)
2.测试安装成功没有:黑窗口直接敲命令,windows下:soffice –convert-to pdf example.docx
linux下: doc2pdf example.docx, windows需要添加path系统变量(C:\Program Files\LibreOffice 5\program),不然无法识别soffice命令
3.如果没有字体错误请跨过
如果有字体错误请参考这个https://blog.csdn/frylion/article/details/8207259把字体复制到/usr/share/fonts下。
sudo cp -r dir1 dir2
代码
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import java.time.Instant;
import org.apachemons.io.IOUtils;
import com.itextpdf.text.pdf.PdfReader;
/**
* @author qjp
*
*/
public class WordPdfUtils {
//测试用
public static void main(String[] args) {
WordPdfUtils.getTotalPageByToPdf("E:/test.docx");
}
//word转换成pdf,生成的pdf会放在同一目录下
//可以通过修改变量command,更改pdf生成的路径
public boolean wordConverterToPdf(String docxPath) throws IOException {
File file = new File(docxPath);
String path = file.getParent();
Instant inst1 = Instant.now();
try {
String osName = System.getProperty("os.name");
String command = "";
if (osName.contains("Windows")) {
//soffice --convert-to pdf -outdir E:/nctcFile/报告 E:/nctcFile/报告/20171107_报告_IC卡读写机_2018.4.23_19时59分.docx
command = "soffice --convert-to pdf -outdir " + path + " " + docxPath;
} else {
command = "doc2pdf --output=" + path + File.separator + file.getName().replaceAll(".(?i)docx", ".pdf") + " " + docxPath;
}
String result = WordPdfUtils.executeCommand(command);
System.out.println("生成pdf的result==" + result);
if (result.equals("") || result.contains("writer_pdf_Export")) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
try {
throw e;
} catch (Exception e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
}
Instant inst2 = Instant.now();
System.out.println("生成pdf耗费时间: " + Duration.between(inst1, inst2).getSeconds() + "秒");
return false;
}
/*
* 获取pdf总页数
*/
public static int getPdfPage(String filepath){
int pagecount = 0;
PdfReader reader;
try {
reader = new PdfReader(filepath);
pagecount= reader.getNumberOfPages();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("pdf的总页数为:" + pagecount);
return pagecount;
}
/*
* 把word转换成pdf,并获取总页数
*/
public static int getTotalPageByToPdf(String sourceFile) {
try {
new WordPdfUtils().wordConverterToPdf(sourceFile);
sourceFile = sourceFile.replace(".docx", ".pdf");//pdf是同名不同后缀
int totalPage = WordPdfUtils.getPdfPage(sourceFile);
return totalPage;
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return 0;
}
}
/**
* linux或windows命令执行
*/
public static String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
inputStreamReader = new InputStreamReader(p.getInputStream(), "UTF-8");
reader = new BufferedReader(inputStreamReader);
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
// p.destroy();//程序会自己销毁
} catch (IOException e) {
e.printStackTrace();
return "执行生成pdf的命令行IOException时出错";
} catch (InterruptedException e) {
e.printStackTrace();
return "执行生成pdf的命令行时InterruptedException出错";
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(inputStreamReader);
}
System.out.println(output.toString());
return output.toString();
}
}
这样,最后就能获取word的总页数了,如果程序出了bug,欢迎给我留言~
更多推荐
linux、windows word转成pdf 来获取总页数 + POI修改word内容
发布评论