【java】doc转pdf

市场上主流的 WORD 转 PDF 工具有两个:OpenOffice 和 Microsoft Office 转
换插件,可以通过部署这两个工具实现 WORD 转 PDF 功能。

1:

Microsoft 提 供 了 一 个 转 换 插 件 实 现 Office 转 PDF 功 能 , 即
SaveAsPDFandXPS。此插件是一个 com 组件,对于 C++、C#等语言可以直接使
用,如果是 JAVA 语言,需要通过 jacob 来调用 com 组件。
SaveAsPDFandXPS 插件要求必须有一台 Windows 服务器作为转换服务器安
装部署 Microsoft Office2007 以上的版本,然后再安装 SaveAsPDFandXPS 插件。
最后调用 com 组件实现转换。
官网地址:https://msdn.microsoft.com/en-us/library/dd301166(v=nav.90).aspx

2.

OpenOffice 是个开源的办公套件,提供了与 MS Word,Excel,PowerPoint 等
对应的多个软件,它支持包括 MS Office 2007 在内的多种格式,并且能够将其导
出为 PDF 文件。
这个方案是在 linux 服务器上安装 openOffice 然后通过 openOffice 命令来转换
pdf。
官方网址:http://www.openoffice.org/

在ubuntu下:

  1. tar -xvzf Apache_OpenOffice_4.1.3_Linux_x86-64_install-deb_zh-CN.tar.gz   
  2. cd zh-CN/DEBS/  
  3. sudo dpkg -i *.deb  
  4. cd desktop-integration/  
  5. sudo dpkg -i openoffice4.1-debian-menus_4.1.3-9783_all.deb  

soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard &  

启动服务,# netstat -an|more,可查看是否启动成功(是否有8100端口的服务)

package openofficeTest;  
  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.net.ConnectException;  
  
import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;  
import com.artofsolving.jodconverter.DocumentConverter;  
import com.artofsolving.jodconverter.DocumentFormat;  
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;  
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;  
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;  
  
  
public class Word2Pdf {  
   
    public static int PORT = 8100;  public static void main(String[] args){  

     String path1 = "/tmp/1.doc";  
     String path2 = "/tmp/2.pdf";  
        try {  
            wordToPdf(path1, path2);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
      
 
    public static void wordToPdf(String path1, String path2)  
            throws Exception {  
        File file1 = new File(path1);  
        File file2 = new File(path2);  
        // 获得文件格式  
        DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry();  
        DocumentFormat pdfFormat = formatReg.getFormatByFileExtension("pdf");  
        DocumentFormat docFormat = formatReg.getFormatByFileExtension("doc");  
        // stream 流的形式  
        InputStream inputStream = new FileInputStream(file1);  
        OutputStream outputStream = new FileOutputStream(file2);  
   
        /** 
         *  
         */  
        OpenOfficeConnection connection = new SocketOpenOfficeConnection(PORT);  
        System.out.println(connection);  
        try {  
   
            connection.connect();  
            DocumentConverter converter = new OpenOfficeDocumentConverter(connection);  
            converter.convert(inputStream, docFormat, outputStream, pdfFormat);  
        } catch (ConnectException e) {  
            e.printStackTrace();  
        } finally {  
            if (connection != null) {  
                connection.disconnect();  
                connection = null;  
            }  
        }  
    }  
   
  
}  

 但是,经过测试,openoffice转换的速度明显很慢,主要是在获取OpenOfficeConnection这块,我目前还没有找到能明显提升速度的方法,下面还有第三种基于libreoffice做转换的方式。

前提条件:要安装libreoffice, libreoffice-headless

安装命令:

yum install libreoffice -y

yum install libreoffice-headless -y

转换命令:libreoffice --headless --convert-to pdf:writer_pdf_Export --outdir /tmp/ /tmp/test.doc

其中/tmp/test.doc为测试用的doc文件,生成的pdf文件会在/tmp/下,名称会默认和doc的名字一样。

遇到的问题:pdf文件中如果中文变成了框框

解决方法:让linux支持中文

1:yum groupinstall "fonts"
2:vim /etc/locale.conf
将原来的 LANG=en_US.UTF-8,前面加上#号注释掉
新增 LANG=zh_CN.UTF-8
3:source /etc/locale.conf

 

 

下面是项目中以doc文件流输入,返回pdf文件流的方法。

public static byte[] toPDF(byte[] b, String sourceFileName) throws Exception{
        
        File tempDir = null;
        try{
            tempDir = Files.createTempDir();
            
            String canonicalPath = tempDir.getCanonicalPath();
            
            File file = new File(canonicalPath + "/" + sourceFileName);

            OutputStream os = new FileOutputStream(file);

            BufferedOutputStream bufferedOutput = new BufferedOutputStream(os);

            bufferedOutput.write(b);
            
            String command = "libreoffice";
            
            Process proc = new ProcessBuilder(command, "--headless", "--convert-to", "pdf:writer_pdf_Export", "--outdir", canonicalPath, canonicalPath + "/" + sourceFileName)
                               .redirectErrorStream(true)
                               .start(); 
            
            ArrayList<String> output = new ArrayList<String>();
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null)
                output.add(line);
            
            logger.info("执行pdf转换命令的输出:" + StringUtils.join(output, System.lineSeparator()));
            
            if (0 != proc.waitFor())
                throw new Exception("转换失败");
            
            File[] files = tempDir.listFiles();
            for (File file2 : files) {
                if (file2.getPath().endsWith(".pdf")) {
                    return IOUtils.toByteArray(new FileInputStream(file2));
                }
            }
            return null;
        }finally{
            if(tempDir != null)
                FileUtils.deleteDirectory(tempDir);
        }
    }

 

posted @ 2017-07-31 18:49  让我发会呆  阅读(1271)  评论(3编辑  收藏  举报