Java word转pdf Linux/windows跨平台 格式完美(利用命令行调用libreoffice)

参考了里面的libreoffice的用法:https://blog.csdn.net/qwert678000/article/details/72770109

需求描述

最近在做word报表的自动生成,甲方要求要有pdf格式,且对样式要求特别严格。
上网搜了很多,发现在对word样式要求特别高的情况下,用libreoffice是特别好的选择。
基本上几秒钟10多页就出来。如果对样式要求不高,可以尝试其他的方法(aspose是个很好用的word->pdf的库)。

步骤

1.安装libreoffice(linux还需要装unoconv),windows到官网下载安装包,linux直接用命令行装即可:
https://zh-cn.libreoffice.org/get-help/install-howto/linux/(linux版及libreoffice中文官网)

2.验证安装是否成功
黑窗口直接敲命令,windows下:soffice --convert-to pdf example.docx
linux下: doc2pdf example.docx, windows需要添加path系统变量(C:\Program Files\LibreOffice 5\program),不然无法识别soffice命令

3.写代码

WordPdfUtils类:Word转Pdf主类

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.MapUtils;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.opensagres.xdocreport.utils.StringUtils;

/**
 * @author Rocca
 *
 */
public class WordPdfUtils {

	protected static final Logger logger = LoggerFactory.getLogger(WordPdfUtils.class);

	public boolean wordConverterToPdf(String docxPath) throws IOException {
	    File file = new File(docxPath);
	    String path = file.getParent();
	    try {
	        String osName = System.getProperty("os.name");
	        String command = "";
	        if (osName.contains("Windows")) {
	        	//soffice --convert-to pdf  -outdir E:/test.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 = CommandExecute.executeCommand(command);
//	        LOGGER.info("result==" + result);
	        System.out.println("生成pdf的result==" + result);
	        if (result.equals("") || result.contains("writer_pdf_Export")) {
	            return true;
	        }
	    } catch (Exception e) {
	        e.printStackTrace();
	        throw e;
	    }
	    return false;
	}
	
	//测试用
	public static void main(String[] args) {
		try {
			// 建议都用/左斜杠这种,左斜杠是windows和linux通用的
			new WordPdfUtils().wordConverterToPdf("E:/test.docx");
		} catch (IOException e) {
			System.out.println("word转换成pdf时出错");
			e.printStackTrace();
		}
	}
}

CommandExecute类:执行linux或windows命令行

package com.bupt.nctc.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.io.IOUtils;

/**
 * linux或windows命令执行
 */
public class CommandExecute {

//    public static void main(String[] args) {
//        CommandExecute obj = new CommandExecute();
//        String domainName = "www.baidu.com";
//        //in mac oxs
//        String command = "ping " + domainName;
//        //in windows
//        //String command = "ping -n 3 " + domainName;
//        String output = obj.executeCommand(command);
//        System.out.println(output);
//    }

    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();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(reader);
            IOUtils.closeQuietly(inputStreamReader);
        }
        System.out.println(output.toString());
        return output.toString();

    }
}

备注:里面的main(0方法去掉注释后,可以用来做测试

4.解决中文乱码问题

复制windows的常用字体到linux下(常用字体如宋体、黑体)
可以先把字体文件夹复制到linux下的某个文件夹下,然后复制到目标位置:
如:sudo cp -r dir1 dir2
在我的电脑上是:sudo cp -r /home/nctc/fonts /usr/share/fonts就可以完成了。(试过2次都行)
上面是参考了这个https://blog.csdn.net/frylion/article/details/8207259把字体复制到/usr/share/fonts下。

  • 10
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 59
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 59
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值