• Java 处理word文档后在前端展示


       

            最新新开发的这个项目需要使用word文档并要求能在前端页面上带格式展示,由于项目不是内部使用,所以不考虑插件类的处理模式,都必须要本地处理完成,前端不需要做什么更新或者说安装就能直接访问,类似于百度文库这种。

    • 首先想到的是JSP能不能直接显示word文档呢?

            然后找了很多资料,逛了很多论坛,发现很多人说可以,只要在处理的时候页面头上加上<%@page contentType="application/msword;charset=GBK" %> ,不知是我水平不够,还是有什么地方没有注意到,最终的结果都是提示下载或者是使用word打开,没有想象中的在jsp端直接显示的。

           外面都是这种或类似这种意思:

    <%@ page contentType="application/msword;charset=gb2312" %>
    
    <% 
        File f=new File("D:/Tomcat 5.5/webapps/neiwang/txt/telephone.doc");
        FileInputStream fin=new FileInputStream(f);
        OutputStream output=response.getOutputStream();
        byte[] buf=new byte[1024];
        int r=0;
        response.setContentType("application/msword;charset=GB2312");
        while((r=fin.read(buf,0,buf.length))!=-1)
        {
            output.write(buf,0,r);//response.getOutputStream()
         }
        fin.close();
        output.close();
    %>

            我做了一些尝试,发现根本无法显示,最终的结果都是提示下载。我想说的是,作为一个技术,发出来的解答首先你得自己能实现吧,不过帖子时间也比较久远了,可能当时确实是可以的或者说只是我不会而已,多说无益。既然这种办法处理不了,只能另寻他法。

    • 我换了个方法就是将 word 转换成 html ,再通过jsp来访问这个链接

    这个是个比较传统的解决思路,搜一搜其实发现很多人都这么干,这批人难道也是对上述方法(jsp直接显示)失望了后找的这种模式?呵呵

    比较常用的开源免费的有且只有几种,选择其中几种我尝试了一下。

            首先想到的是POI,但处理 Word 没有想象的中的那样优秀,出来的基本一团糟,没有任何格式性可谈,而且需要一个字符一个字符的处理特别费力,结果不理想代码就不贴了,曾使用它来处理过 Excel 觉得还很优秀!

            然后就另找了一个叫 OpenOffice,经过尝试发现经过它转换出来的文档,虽然缺失格式,但也不是不能接受,自己再另行加处理也许能成。将Word转Html的原理是这样的:

            1、客户上传Word文档到服务器

            2、服务器调用OpenOffice程序打开上传的Word文档

           3、OpenOffice将Word文档另存为Html格式

    基于这个基础上的实现需要下载 openOffice 。

    1、下载 OpenOffice,http://download.openoffice.org/index.html 

    2、下载 Jodconverter,http://www.artofsolving.com/opensource/jodconverter  这是开启OpenOffice进行格式转化的第三方jar包。

    3、安装 OpenOffice,成功后在安装目录下启动监听端口:

         soffice -headless -accept="socket,port=8100;urp;"

         可以通过 netstat –an|findstr “8100” 查看端口是否监听;如图

        image

    4、打开Eclipse新建项目,导入Jodconverter/lib 下面的 jar 。具体的需要哪些自己可以尝试。我比较懒就都添加了。

         image

       

    下面是代码:

    import java.io.File;
    import java.net.ConnectException;
    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;
    
    public class OfficeConverter {
    
        public static void main(String[] args) {
            File inputFile = new File("C:/test/yy.doc");
            File outputFile = new File("C:/test/yy.html");
            
            OpenOfficeConnection con = new SocketOpenOfficeConnection(8100);
            try {
                con.connect();
            } catch (ConnectException e) {
                System.err.println("文件转换出错,请检查OpenOffice服务是否启动。");
                e.printStackTrace();
            }
            DocumentConverter converter = new OpenOfficeDocumentConverter(con);
            converter.convert(inputFile, outputFile);
            con.disconnect();
        }
    }

    总结:使用OpenOffice作为转换引擎把word文档转换成html,比起使用微软的com组件有跨平台的优势,而且比Apache poi(POI貌似只能获取word中的文本内容,图片和表格,图片和表格的定位很是个问题,获取样式要一个字符一个字符的分析麻烦且效率低下)方便且简单,但是个人觉得这个结果其实并不理想,排版仍然缺失很严重。

    普通情况下的排版差别见下图:

    imageimage

    通过程序读取解析后的文档格式如下图,经过对比貌似比 word 自身的另存为还好看点,相信经过不断优化以后应该能完美支持解析。但是细心点还是会看见单元格样式变了,排版变了,如果要求不是太高,这个也能满足需求了。

    image


    不过如果只需要保存相关的文字的话,上面转化的html内容冗余比较多,可以用 java 正则表达式来处理多余字符串,详见下面的代码:

    protected static String clearFormat(String htmlStr, String docImgPath) {
            // 获取body内容的正则
            String bodyReg = "<BODY .*</BODY>";
            Pattern bodyPattern = Pattern.compile(bodyReg);
            Matcher bodyMatcher = bodyPattern.matcher(htmlStr);
            if (bodyMatcher.find()) {
                // 获取BODY内容,并转化BODY标签为DIV
                htmlStr = bodyMatcher.group().replaceFirst("<BODY", "<DIV").replaceAll("</BODY>", "</DIV>");
            }
            // 调整图片地址
            htmlStr = htmlStr.replaceAll("<IMG SRC=\"", "<IMG SRC=\"" + docImgPath + "/");
            // 把<P></P>转换成</div></div>保留样式
            htmlStr = htmlStr.replaceAll("(<P)([^>]*>.*?)(<\\/P>)", "<div$2</div>");
            // 把<P></P>转换成</div></div>并删除样式
            htmlStr = htmlStr.replaceAll("(<P)([^>]*)(>.*?)(<\\/P>)", "<p$3</p>");
            // 删除不需要的标签
            htmlStr = htmlStr
                    .replaceAll("<[/]?(font|FONT|span|SPAN|xml|XML|del|DEL|ins|INS|meta|META|[ovwxpOVWXP]:\\w+)[^>]*?>","");
            // 删除不需要的属性
            htmlStr = htmlStr
                    .replaceAll("<([^>]*)(?:lang|LANG|class|CLASS|style|STYLE|size|SIZE|face|FACE|[ovwxpOVWXP]:\\w+)=(?:'[^']*'|\"\"[^\"\"]*\"\"|[^>]+)([^>]*)>","<$1$2>");
            // 删除<STYLE TYPE="text/css"></STYLE>及之间的内容
            int styleBegin = htmlStr.indexOf("<STYLE");
            int styleEnd = htmlStr.indexOf("</STYLE>") + 8;
            String style = htmlStr.substring(styleBegin, styleEnd);
            htmlStr = htmlStr.replace(style, "");
    
            return htmlStr;
        }

    这个OpenOffice基本使用就介绍完了,自己如果有更多需求的话可以去查查资料看怎么更完善,谢谢分享。

    http://dangry.iteye.com/blog/858787

  • 相关阅读:
    Openssl命令详解
    Openssl命令详解
    Mac根目录下无法创建文件或目录
    解决 mysql from_base64 函数返回乱码的问题
    elementUI日期选择器 el-date-picker根据所选日期选择禁用
    el-dialog设置为点击弹窗以外的区域不自动关闭弹窗
    在vue项目中MD5加密的使用方法
    bower install 报错fatal: unable to access 'https://github.com/angular/bower-angular-touch.git/'类错误解决方法
    angular项目grunt serve报错Cannot find where you keep your Bower packages
    移动端开发--》适配各种机型样式大小
  • 原文地址:https://www.cnblogs.com/laramia/p/4933104.html
Copyright © 2020-2023  润新知