linux、windows word转成pdf 来获取总页数 + POI修改word内容

背景

因为本来用的是POI,调研了一些POI的api,虽然有一些获取总页数的方法,但是一旦word里有图片获得的总页数就不准确了。
看有大牛提到过用转pdf的方法来获取word总页数,但是只适用于windows平台下,但我们甲方的服务器是Linux的,所以才采用了另一款转pdf的工具–Libreoffice

解决方法

1.对于没有图片的word,可以尝试调用下代码:
参考:https://stackoverflow.com/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.org/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.net/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.apache.commons.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,欢迎给我留言~

你可能感兴趣的:(文本处理)