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完成了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现将 HTML 导出带页码的 Word 并配置样式和分页功能,需要使用一些第三方库和工具。下面是一些实现步骤: 1. 使用 jsPDF 库将 HTML 转换为 PDF 格式。 2. 使用 PDFmake 库将 PDF 转换Word 文档。 3. 配置样式和分页功能。 下面是具体实现步骤: 1. 将 HTML 转换为 PDF 格式 使用 jsPDF 库将 HTML 转换为 PDF 格式。需要先引入 jsPDF 库: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"></script> ``` 然后使用以下代码将 HTML 转换为 PDF 格式: ```javascript const doc = new jsPDF(); doc.html(document.body, { callback: function (doc) { doc.save('test.pdf'); }, x: 10, y: 10 }); ``` 这里的 `document.body` 可以替换为要导出的 HTML 元素。 2. 将 PDF 转换Word 文档 使用 PDFmake 库将 PDF 转换Word 文档。需要先引入 PDFmake 库: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.2/pdfmake.min.js"></script> ``` 然后使用以下代码将 PDF 转换Word 文档: ```javascript const pdfDocGenerator = pdfMake.createPdf(doc.output('blob')); pdfDocGenerator.getBlob((blob) => { const fileReader = new FileReader(); fileReader.readAsArrayBuffer(blob); fileReader.onloadend = () => { const arrayBuffer = fileReader.result; const byteArray = new Uint8Array(arrayBuffer); const blob = new Blob([byteArray], { type: 'application/msword' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'test.docx'; document.body.appendChild(a); a.click(); }; }); ``` 这里的 `doc` 是上一步中生成的 PDF 对象。 3. 配置样式和分页功能 使用 PDFmake 库可以很方便地配置样式和分页功能。可以使用以下代码配置样式: ```javascript const styles = { header: { fontSize: 18, bold: true }, subheader: { fontSize: 14, bold: true }, tableHeader: { bold: true, fontSize: 13, color: 'black' }, tableRow: { fontSize: 12 } }; const content = [ { text: 'Header', style: 'header' }, { text: 'Subheader', style: 'subheader' }, { style: 'table', table: { headerRows: 1, body: [ [ { text: 'Table Header 1', style: 'tableHeader' }, { text: 'Table Header 2', style: 'tableHeader' }, { text: 'Table Header 3', style: 'tableHeader' } ], [ { text: 'Table Row 1', style: 'tableRow' }, { text: 'Table Row 2', style: 'tableRow' }, { text: 'Table Row 3', style: 'tableRow' } ] ] } } ]; ``` 这里的 `styles` 对象定义了不同的样式,`content` 数组定义了要导出的内容。 要实现分页功能,可以在 PDFmake 中使用 `pageBreak` 属性。例如: ```javascript { text: 'This text will be on page 1', pageBreak: 'after' }, { text: 'This text will be on page 2', pageBreak: 'before' }, { text: 'This text will be on page 2 as well', }, ``` 这里的 `pageBreak` 属性可以设置为 `before`, `after` 或 `avoid`,分别表示在当前元素前插入分页符、在当前元素后插入分页符或避免分页
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值