OpenOffice在线预览附件

OpenOffice在线预览附件

Author [email protected]

Date 2018/1/20

Desc 在线预览附件功能

1.下载安装包

官方下载: http://www.openoffice.org/download/index.html

image.png

2.安装OpenOffice

此处对于安装过程针对windows 和 linux两种环境分别介绍:

Windows安装
  • 双击安装包 打开运行程序 —-> 点击下一步按钮 —-> 点击浏览按钮 选择安装目录路径 —–> 会自动检测系统中的插件 如果需要会自动安装 —–> 输入使用的用户 以及选择用户权限 点击下一步按钮 —–> 勾选通常安装 点击下一步 —-> 点击完成 即安装结束

  • 接下来以命令方式启动OpenOffice服务

    cd  C:\Program Files (x86)\OpenOffice 4\program
    soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard

服务打开成功之后在任务管理器可以看见soffice.bin的进程。

注意: 使用OpenOffice的时候一定要打开服务 !

比如我自己电脑晚上关机了,服务就自己关闭, 使用预览功能时候会报错:
java.net.ConnectException: connection failed: socket,host=127.0.0.1,port=8100,tcpNoDelay=1: java.net.ConnectException: Connection refused: connect at .....
Linux安装

linux安装教程可以参考网址:https://www.cnblogs.com/goodcheap/p/7929986.html

  • 启动服务和windows不同的是,需要在命令末尾加 &

    cd /opt/openoffice4/program
    soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &
  • 查看服务是否成功启动

    [root@vs058 program]# ps -ef|grep openoffice
    root     24818 24804 19 15:08 pts/4    00:00:00 /opt/openoffice4/program/soffice.bin -headless -accept=socket,host=127.0.0.1,port=8100;urp; -nofirststartwizard
    root     24824 24592  0 15:08 pts/4    00:00:00 grep openoffice
    
    [root@vs058 program]# netstat -lnp |grep 8100
    tcp        0      0 127.0.0.1:8100              0.0.0.0:*                   LISTEN      24818/soffice.bin   

3.引入jodconverter-2.2.2.jar包

引入jar包的过程摸索了很久, 对于一般的java项目,直接将jar包放在lib下就可以调用; 但是恰巧我用的是maven项目, 这就需要在maven中寻找依赖, 对于我这个maven新手而言,只听过maven,见过表面的maven,并没有很深入而又熟练地掌握它的用法,尤其是碰到在pom.xml中引入依赖这种问题. 只能很羞愧地寻求小伙伴的帮助或者百度.

4.前台代码

在附件上传界面可以上传文件,也可以获取到文件列表的详细信息, 比如 文件在服务器上的路径,还有文件名称

image.png

image.png

既然文件路径都获得到了, 那我们直接将文件路径和文件名称传递到后台进行预览, 代码如下:

“`

kendoUI-Grid:

{
field: “”,
headerAttributes: {
style: “text-align: center”
},
attributes: {style: “text-align:center”},
title: ‘预览’,
width: 50,
template: function (e) {
return ‘

5.后台代码

  • 首先我们要根据System.getProperty("os.name")获得服务器类别, 然后自由转换文件路径, 比如linux就是`"/",windows就是"\"

  • 对于HAP框架来说, 文件上传到服务器时是不带后缀名的,这个时候利用jodconverter将docx文件转换为pdf文件时就会出现错误java.lang.IllegalArgumentException: unknown document format for file:, 所以我们就要改造框架封装好的上传方法,此处不做介绍. 或者通过file.renameto(newFile)将文件重命名为带后缀的,但是我们下载的功能就要随之修改咯 !

  • 然后根据不同的文件扩展名设置ContentType:http://tool.oschina.net/commons

  • 然后连接端口号8100, 这个端口号和打开OpenOffice服务的端口号是一致的, 然后通过converter.convert(docFile, pdfFile);将文件成功转换为 .pdf后缀的文件

    image.png

  • 将文件写到输出流中,显示在界面上,实现预览效果

详细代码如下:

/**
     * 在线预览图片
     * @param request
     * @param response
     * @param filePath
     * @param fileName
     * @throws IOException
     */
    @RequestMapping(value = "/sys/attach/preview")
    public ResponseData preview(HttpServletRequest request, HttpServletResponse response, @RequestParam String filePath, @RequestParam String fileName) throws IOException {
        IRequest requestContext = this.createRequestContext(request);
        ResponseData responseData = new ResponseData();
        response.setContentType("text/html; charset=UTF-8");

        if(!"".equals(filePath)) {
            /*1)根据项目所在的服务器环境,确定路径中的 /  和 \ */
            String osName = System.getProperty("os.name");
            if (Pattern.matches("Linux.*", osName)) {
                filePath = "/" + filePath.replace("\\","/");
            } else if(Pattern.matches("Windows.*", osName)) {
                filePath.replace("/","\\");
            }

            /*2)获得文件名后缀*/
            String ext = "";
            if(!"".equals(fileName) && fileName.contains(".")){
                ext = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toUpperCase();
            }

            /*3)根据文件类型不同进行预览*/
            /*预览图片*/
            if ("PNG".equals(ext) || "JPEG".equals(ext) || "JPG".equals(ext)) {
                response.setContentType("image/jpeg");
            }
            /*预览BMP格式的文件*/
            if ("BMP".equals(ext)) {
                response.setContentType("image/bmp");
            }
            /*预览pdf*/
            if ("PDF".equals(ext)) {
                response.setContentType("application/pdf");
            }

            /*利用openOffice将office文件转换为pdf格式, 然后预览doc, docx, xls, xlsx, ppt, pptx */
            if ("DOC".equals(ext) || "DOCX".equals(ext) || "XLS".equals(ext) || "XLSX".equals(ext) || "PPT".equals(ext) || "PPTX".equals(ext)) {
                /*filePath在数据库中是不带文件后缀的, 由于jodConverter必须要识别后缀,所以将服务器中的文件重命名为带后缀的文件*/
                File docFile = new File(filePath);
                /*File docFileWithExt = new File(filePath + "." + ext.toLowerCase()); //带后缀的文件
                docFile.renameTo(docFileWithExt);
                */
                /*转换之后的文件名*/
                File pdfFile;
                if(filePath.contains(".")){
                    pdfFile = new File(filePath.substring(0, filePath.lastIndexOf(".")) + ".pdf");
                }else{
                    pdfFile = new File(filePath + ".pdf");
                }

                /*判断即将要转换的文件是否真实存在*/
                if (docFile.exists()) {
                    /*判断改文件是否已经被转换过,若已经转换则直接预览*/
                    if (!pdfFile.exists()) {
                        /*打开OpenOffice连接,*/
                        OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
                        try {
                            connection.connect();
                            DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
                            converter.convert(docFile, pdfFile);
                            connection.disconnect();

                            filePath = pdfFile.getPath(); //文件转换之后的路径
                            response.setContentType("application/pdf");

                        } catch (java.net.ConnectException e) {
                            e.printStackTrace(); //openoffice 服务未启动
                            throw e;
                        } catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
                            e.printStackTrace(); //读取转换文件失败
                            throw e;
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw e;
                        }finally { //发生exception时, connection不会自动切断, 程序会一直挂着
                            try{
                                if(connection != null){
                                    connection.disconnect();
                                    connection = null;
                                }
                            }catch(Exception e){}
                        }
                    } else {
                        filePath = pdfFile.getPath(); //文件已经转换过
                        response.setContentType("application/pdf");
                    }
                } else {
                    responseData.setSuccess(false);
                    responseData.setMessage("需要预览的文档在服务器中不存在!");
                    return responseData;
                }
            }

            /*将文件写入输出流,显示在界面上,实现预览效果*/
            FileInputStream fis = new FileInputStream(filePath);
            OutputStream os = response.getOutputStream();
            try {
                int count = 0;
                byte[] buffer = new byte[1024 * 1024];
                while ((count = fis.read(buffer)) != -1)
                    os.write(buffer, 0, count);
                os.flush();
                responseData.setSuccess(true);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (os != null)
                    os.close();
                if (fis != null)
                    fis.close();
            }
        }
        return responseData;
    }

总结,转换文件的核心代码就下边几句:

OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
connection.connect();
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
converter.convert(docFile, pdfFile);
connection.disconnect();

实现效果如下:

npm jpg格式:

image.png

.doc格式:

image.png

.docx格式:

image.png

.pdf格式:

image.png

问题1:Uncaught SyntaxError: Invalid Unicode escape sequence

javaScrip上传文件路径字符串时, 一定要使用转义字符 ! ! ! 否则会报错

image.png

问题2:unknown document format for file

openOffice 将.docx文件转换为.pdf时出错

2018-01-18 20:10:23.312 DEBUG [10001] [1804f437cb4f400f9f22b4b0816c02c9] com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection - connecting
2018-01-18 20:10:23.860 INFO  [10001] [1804f437cb4f400f9f22b4b0816c02c9] com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection - connected
java.lang.IllegalArgumentException: unknown document format for file: D:\usr\pictures\hap\img\787dc887-9dba-4c7b-969a-c5b497268f9f

debug 代码: converter.convert(docFile, pdfFile); 首先判断是不是文件路径有错误 ,如下 路径没有问题

image.png

再根据错误信息追溯jodconverter源码, 发现错误信息在这里:

” . “的unicode字符是46 , 所以这行代码的意思是定位 ” . ” 所在的位置, 而我们服务器的文件是没有后缀的,所以报错, 找到问题的原因就知道怎么解决问题了.

猜你喜欢

转载自blog.csdn.net/a1786223749/article/details/79461070