Word转换Html后分页展示--第一部分

前言

       Word上传后转换为Html的问题已经解决,那么现在问题来了,如果Word内容较多特别是图片文件,在网页上查看时,加载会耗时耗流量。解决方案就是分页加载,类似百度文库的方式。百度文库对Word显示是Html的,网上使用更多的一种解决方案是用Flash控件,如FlexPaper。

       现在我们使用Html的分页方式。在Java中没有找到现成的方法读取Word中的分页数据,生成的Html文件也没有对分页特别标记。最开始的思路是把Html内容全部存到数据库,分页读取,可不知道一次读取多少,也不能用文字个数划分,因为Word里面有空格,字体大小不一样,还有图片。灵感来源是在浏览器中看生成的Html时,偶然想到的。在浏览器里面Html元素是有像素高度的,通过每个元素高度来划分分页,比如600px高度为一页内容。也就是说分页的计算交给浏览器去完成,把浏览器当做一个服务来用。

步骤

       1. 使用Jacob转换完Html后,自动调用浏览器打开Html文件

       2. 浏览器执行Html里面的js方法,完成分页计算,并关闭界面

       3. 保存每页内容到数据库,并提供读取方法

       4. 生成查看界面,包含分页加载方法

环境

       1. Tomcat7,使用Websocket需要用到里面的tomcat-coyote.jar、catalina.jar

       2. Jdk6.0

       3. 猎豹浏览器

实现

       使用Jacob将Word转换为Html请看之前的文章,现在需要实现的是Html生成后,由浏览器自动打开。方案有两种,一是定时查询,当发现有新的Html即Open打开一个新窗口,路径由查询返回;二是用Websocket与服务端建立连接,Html生成后由服务端告知浏览器打开一个新窗口。这里我使用第二种方式。

先给出Websocket界面上的代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML>  
<html> 
<head>  
	<title>WebSocket</title>  
	<style>  
		body {
			padding: 10px;
		}  
		#outputPanel {
			background: #f3f3f3;
			border: 1px solid #666;
			min-height: 400px;
			width: 600px;
		}  
	</style>  
</head>  
<body>  
	<input type="button" id="buttonConnect" value="连接服务器" />  
	<input type="button" id="buttonClose" value="断开服务器" />  
	<br>  
	<div id="outputPanel"></div>  
</body>  
<script type="text/javascript">  
    var infoPanel = document.getElementById('outputPanel'); // 输出结果面板  
    var connButton = document.getElementById('buttonConnect');// 建立连接按钮  
    var discButton = document.getElementById('buttonClose');// 断开连接按钮  
    // 控制台输出对象  
    var console = {log : function(text) {infoPanel.innerHTML += text + "<br>";}};  
    // WebSocket演示对象  
    var demo = {  
        socket : null,  // WebSocket连接对象  
        host : '',      // WebSocket连接 url  
        connect : function() {  // 连接服务器  
            window.WebSocket = window.WebSocket || window.MozWebSocket;  
            if (!window.WebSocket) {    //检测浏览器支持  
                console.log('浏览器不支持Websocket');  
                return;  
            }  
            this.socket = new WebSocket(this.host); // 创建连接并注册响应函数  
            this.socket.onopen = function(){console.log("websocket打开");};  
            this.socket.onmessage = function(message) {
            	console.log(message.data);
            	if(message.data.indexOf(".html") > 0){
            		window.open("http://127.0.0.1:8081/wordconvert/"+message.data,
            		'win',"height=600,width=620");
            	}
            };  
            this.socket.onclose = function(){  
                console.log("websocket关闭");  
                demo.socket = null; 
            }; 
        }  
    };  
    // 初始化WebSocket连接 url  
    demo.host=(window.location.protocol == 'http:') ? 'ws://' : 'wss://' ;  
    demo.host += window.location.host + '/wordconvert/websocket/say';  
    connButton.onclick = function() {  
        if (!demo.socket){
        	demo.connect(); 
        }
    };  
    discButton.onclick = function() {  
        if (demo.socket) {
        	demo.socket.close();  
        } 
    };  
</script>
</html>
关键地方在第46行,根据返回的messge打开界面。

后台用到3个类,分别是WordServlet,前端Websocket是与该类交互的。注意该Servlet是继承自WebSocketServlet

package com.word.websocket;

import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;

public class WordServlet extends WebSocketServlet{
	
	@Override
	protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest arg1) {
		return new MessageInBound(arg1.getSession().getId());
	}
	
}
第2个类是MessageInBound,该类是Websocket实际工作的地方,有Open、send等监听方法

package com.word.websocket;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.CharBuffer;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WsOutbound;

public class MessageInBound extends StreamInbound{

    private String sessionId = "";  
    
	public String getSessionId() {
		return sessionId;
	}

	public MessageInBound(String _sessionId) {  
        this.sessionId = _sessionId;  
    } 
	
	@Override  
    protected void onTextData(Reader reader) throws IOException {  
        char[] chArr = new char[1024];  
        int len = reader.read(chArr);  
        WebSocketMessageInboundPool.sendMessage(String.copyValueOf(chArr, 0, len));
    }  
  
	private void send(String message) throws IOException {
		getWsOutbound().writeTextMessage(CharBuffer.wrap(message));  
    }
	
    @Override
    protected void onOpen(WsOutbound outbound) {  
        super.onOpen(outbound);
        try {
            send("session id = " + this.sessionId);
        } catch (IOException e) {
            e.printStackTrace();
        }
        WebSocketMessageInboundPool.addMessageInbound(this);
    }
	
    @Override  
    protected void onClose(int status) {  
        super.onClose(status);
        WebSocketMessageInboundPool.removeMessageInbound(this);
    }
    
	@Override
	protected void onBinaryData(InputStream arg0) throws IOException {
	}
}
第3个类是WebSocketMessageInboundPool,该类是一个保存Websocket的连接池,当前端点击“连接服务器”时,就会将连接保存起来,用在Html生成时获取该连接池里面连接的对象,向其发送消息,以实现推送效果,当然这也是Websocket的本质功能

package com.word.websocket;

import java.io.IOException;
import java.nio.CharBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class WebSocketMessageInboundPool {
	private static final Map<String,MessageInBound > connections = 
		new HashMap<String,MessageInBound>(); 
	
	public static void addMessageInbound(MessageInBound inbound){  
        connections.put(inbound.getSessionId(), inbound);  
    }  
      
    public static void removeMessageInbound(MessageInBound inbound){  
        connections.remove(inbound.getSessionId());  
    }
    
    public static void sendMessage(String message){  
        try {  
            Set<String> keySet = connections.keySet();  
            for (String key : keySet) {  
            	MessageInBound inbound = connections.get(key);  
                if(inbound != null){  
                    inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(message));  
                }  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}
至此步骤1完成了。


猜你喜欢

转载自blog.csdn.net/f4761/article/details/42618981