java 在线预览doc,pdf

先说一说如何实现在线预览doc

网上查了很多资料,基本思路就是将 doc 转为 pdf,由于低版本浏览器不支持预览 pdf,所以基本是再将 pdf 转为 swf (使用FlexPaper + swftools)
本文使用 pdf.js + jodconverter + openOffice

Java 如何将doc 转为 pdf?

  • poi读取doc + itext生成pdf (实现最方便,效果最差,跨平台)
  • jodconverter + openOffice (一般格式实现效果还行,复杂格式容易有错位,跨平台)
  • jacob + msOfficeWord + SaveAsPDFandXPS (完美保持原doc格式,效率最慢,只能在windows环境下进行)

准备工作

(正式环境部署安装的是libreofficeopenopenOffice的衍生版,之前有些无法转换的doc文件,使用libreoffice后正常转换)
linux上环境所需要的字体包libreoffice https://pan.baidu.com/s/1mjhpdna 密码: 82ca

  • 安装后,使用以下命令可以启动openoffice
    soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
  • windows下查看是否启动
    netstat -ano|findstr "8100"
java 在线预览doc,pdf_第1张图片

Talk is cheap. Show me the code

jodconverter 所需 maven依赖

        
        
            com.artofsolving
            jodconverter
            2.2.1
        

文件转换核心类

import java.io.BufferedInputStream;  
import java.io.File;  
import java.io.IOException;  
import java.io.InputStream;  
  
import com.artofsolving.jodconverter.DocumentConverter;  
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;  
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;  
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;  
  
/** 
 * doc docx格式转换 
 */  
public class DocConverter {  
    private static final int environment = 1;// 环境 1:windows 2:linux  
    private String fileString;// (只涉及pdf2swf路径问题)  
    private String outputPath = "";// 输入路径 ,如果不设置就输出在默认的位置  
    private String fileName;  
    private File pdfFile;  
    private File swfFile;  
    private File docFile;  
      
    public DocConverter(String fileString) {  
        ini(fileString);  
    }  
  
    /** 
     * 重新设置file 
     *  
     * @param fileString 
     */  
    public void setFile(String fileString) {  
        ini(fileString);  
    }  
  
    /** 
     * 初始化 
     *  
     * @param fileString 
     */  
    private void ini(String fileString) {  
        this.fileString = fileString;  
        fileName = fileString.substring(0, fileString.lastIndexOf("."));  
        docFile = new File(fileString);  
        pdfFile = new File(fileName + ".pdf");  
        swfFile = new File(fileName + ".swf");  
    }  
      
    /** 
     * 转为PDF 
     *  
     * @param file 
     */  
    private void doc2pdf() throws Exception {  
        if (docFile.exists()) {  
            if (!pdfFile.exists()) {  
                OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);  
                try {  
                    connection.connect();  
                    DocumentConverter converter = new OpenOfficeDocumentConverter(connection);  
                    converter.convert(docFile, pdfFile);  
                    // close the connection  
                    connection.disconnect();  
                    System.out.println("****pdf转换成功,PDF输出:" + pdfFile.getPath()+ "****");  
                } catch (java.net.ConnectException e) {  
                    e.printStackTrace();  
                    System.out.println("****swf转换器异常,openoffice服务未启动!****");  
                    throw e;  
                } catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {  
                    e.printStackTrace();  
                    System.out.println("****swf转换器异常,读取转换文件失败****");  
                    throw e;  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    throw e;  
                }  
            } else {  
                System.out.println("****已经转换为pdf,不需要再进行转化****");  
            }  
        } else {  
            System.out.println("****swf转换器异常,需要转换的文档不存在,无法转换****");  
        }  
    }  
      
    /** 
     * 转换成 swf 
     */  
    @SuppressWarnings("unused")  
    private void pdf2swf() throws Exception {  
        Runtime r = Runtime.getRuntime();  
        if (!swfFile.exists()) {  
            if (pdfFile.exists()) {  
                if (environment == 1) {// windows环境处理  
                    try {  
                        Process p = r.exec("D:/Program Files/SWFTools/pdf2swf.exe "+ pdfFile.getPath() + " -o "+ swfFile.getPath() + " -T 9");  
                        System.out.print(loadStream(p.getInputStream()));  
                        System.err.print(loadStream(p.getErrorStream()));  
                        System.out.print(loadStream(p.getInputStream()));  
                        System.err.println("****swf转换成功,文件输出:"  
                                + swfFile.getPath() + "****");  
                        if (pdfFile.exists()) {  
                            pdfFile.delete();  
                        }  
  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                        throw e;  
                    }  
                } else if (environment == 2) {// linux环境处理  
                    try {  
                        Process p = r.exec("pdf2swf " + pdfFile.getPath()  
                                + " -o " + swfFile.getPath() + " -T 9");  
                        System.out.print(loadStream(p.getInputStream()));  
                        System.err.print(loadStream(p.getErrorStream()));  
                        System.err.println("****swf转换成功,文件输出:"  
                                + swfFile.getPath() + "****");  
                        if (pdfFile.exists()) {  
                            pdfFile.delete();  
                        }  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                        throw e;  
                    }  
                }  
            } else {  
                System.out.println("****pdf不存在,无法转换****");  
            }  
        } else {  
            System.out.println("****swf已经存在不需要转换****");  
        }  
    }  
  
    static String loadStream(InputStream in) throws IOException {  
  
        int ptr = 0;  
        in = new BufferedInputStream(in);  
        StringBuffer buffer = new StringBuffer();  
  
        while ((ptr = in.read()) != -1) {  
            buffer.append((char) ptr);  
        }  
  
        return buffer.toString();  
    }  
    /** 
     * 转换主方法 
     */  
    @SuppressWarnings("unused")  
    public boolean conver() {  
  
        if (swfFile.exists()) {  
            System.out.println("****swf转换器开始工作,该文件已经转换为swf****");  
            return true;  
        }  
  
        if (environment == 1) {  
            System.out.println("****swf转换器开始工作,当前设置运行环境windows****");  
        } else {  
            System.out.println("****swf转换器开始工作,当前设置运行环境linux****");  
        }  
        try {  
            doc2pdf();  
            pdf2swf();  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
  
        if (swfFile.exists()) {  
            return true;  
        } else {  
            return false;  
        }  
    }  
  
    /** 
     * 返回文件路径 
     *  
     * @param s 
     */  
    public String getswfPath() {  
        if (swfFile.exists()) {  
            String tempString = swfFile.getPath();  
            tempString = tempString.replaceAll("\\\\", "/");  
            return tempString;  
        } else {  
            return "";  
        }  
  
    }  
    /** 
     * 设置输出路径 
     */  
    public void setOutputPath(String outputPath) {  
        this.outputPath = outputPath;  
        if (!outputPath.equals("")) {  
            String realName = fileName.substring(fileName.lastIndexOf("/"),  
                    fileName.lastIndexOf("."));  
            if (outputPath.charAt(outputPath.length()) == '/') {  
                swfFile = new File(outputPath + realName + ".swf");  
            } else {  
                swfFile = new File(outputPath + realName + ".swf");  
            }  
        }  
    }  
  
}  

使用PDF.js

百度网盘: https://pan.baidu.com/s/1dHk0IQH 密码: n47x

将 generic 文件夹复制到项目中即可

我使用的是springboot工程,添加静态资源访问(generic 我重命名为 pdf)

@Configuration
@ComponentScan
public class TXAppConfigurer extends WebMvcConfigurerAdapter implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public TXAppConfigurer() {
        super();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pdf/**")
                .addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/pdf/");
        super.addResourceHandlers(registry);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

请求 http://localhost:8080/pdf/web/viewer.html?file=/displayPDF/4 会跳转到controller

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.txgl.util.DocConverter;
/**
 * 文件预览
 * 
 * @author @Taven
 *
 */
@Controller
public class FilePreview {
    
    @RequestMapping("/displayPDF/{id}")
    public void displayPDF(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) {
        //xxx 逻辑
        // 调用转换类
        DocConverter docConverter = new DocConverter("your filePath");
        try {
            docConverter.doc2pdf();
            File pdf = docConverter.getPdf();
            FileInputStream fileInputStream = new FileInputStream(pdf);
            response.reset();
            response.setHeader("Content-Disposition", "attachment;fileName=test.pdf");
            response.setContentType("multipart/form-data");
            OutputStream outputStream = response.getOutputStream();
            IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

参考博客:
java实现附件预览(openoffice+swftools+flexpaper)
java集成pdf.js实现pdf文件在线预览

你可能感兴趣的:(java 在线预览doc,pdf)