这篇文章主要是围绕如何实现Word文档在页面上进行预览,以及涉及到相关的技术点,和我们将会在这个功能上使用的插件。
插件:Aspose.Total:
Aspose.Total是Aspose公司旗下的最全的一套office文档管理方案,主要提供.net跟java两个开发语言的控件套包,通过它,我们可以有计划地操纵一些商业中最流行的文件格式:Word, Excel, PowerPoint, Project,等office文档以及PDF文档。
在这个功能模块中我们只使用其中的一个强大的类库:Aspose.Words:
Aspose.Words是一款先进的类库,通过它可以直接在各个应用程序中执行各种文档处理任务。Aspose.Words支持DOC,OOXML,RTF,HTML,OpenDocument, PDF, XPS, EPUB和其他格式。使用Aspose.Words,您可以生成,更改,转换,渲染和打印文档而不使用Microsoft Word。
上硬货( 前台代码):
<div id="WordPreview">
<div class="panel panel-info " id="panel1">
<div class="panel-heading">
class="panel-title">Word浏览
div>
<div id="main">
<div id="content">
<div id="contents">
div>
div>
<div class="col-sm-12 padding-t-5" >
<div id="name" class="col-sm-6">div>
<div id="date" class="col-sm-6">div>
div>
div>
div>
div>
这里我们会使用HTML5 的 iframe 标签:
iframe 标签规定一个内联框架,一个内联框架被用来在当前 HTML 文档中嵌入另一个文档,我们将会把Word文档的内容在这个Iframe中显示出来。
JS:
我这里的逻辑是首先选中一个文档触发预览事件,所以我需要有一条这样的代码:
var DocID = getQueryString("DocID");
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
其次我需要向后台发送获取文档和处理文档的请求:
function Preview(id) {
var formData = new FormData();
$.ajax({
type: "post",
url: '../Test.ashx?action=TestPreview&DocID=' + DocID,
async: false,
dataType: "json",
data: formData,
contentType: false,
processData: false,
success: function (result) {
var dataStr = result.Data.split('|');
if (dataStr[0] != "0") {
$('#name').text(dataStr[1]);
document.getElementById('myFrame').src =
'../WordFile' + dataStr[0] + '.html';
$('#date').text(dataStr[2]);
myStyle();
YLID = dataStr[0];
}
},
});
}
最后给我们的显示框设置一下高度和宽度
function myStyle() {
$("#main").width(960);
$("#main").height($('#WordPreview').height() - 100);
$('#content').height($('#main').height() - 50);
$('#myFrame').width(580);
}
现在后台已经拿到我们的请求,并且根据url 解析出我们需要调用的方法
action:TestPreview 和 DocID:DocID。
下面的代码省略了try,catch,只展示了Try中的代码:
//从Session中获取用户基本信息
BLL.User user = context.Session["User"] as BLL.User;
string id = context.Request["DateID"];
int userId = user.UserID;
string sql = "";
string ext = "";
string docName = "";
string submitDate = "";
byte[] bytes = { };
//打开并连接数据库
DBAccess DBA = new DBAccess();
sql = string.Format(@"SELECT DocName,Length,IOStream,ModifyTime FROM dbo.TestWordInfo WHERE ID={0}", id);
//获取文档的详细数据,包括保存在SQL中的文件二进制流
DataTable dt = DBA.GetDataTable(sql);
if (dt.Rows.Count > 0)
{
bytes = new byte[int.Parse(dt.Rows[0]["Length"].ToString())];
//判断是doc还是docx
ext = dt.Rows[0]["DocName"].ToString().EndsWith(".doc") ? ".doc" : ".docx";
//将二进制流保存在byte[]数组中
bytes = (byte[])dt.Rows[0]["IOStream"];
string[] docStr = dt.Rows[0]["DocName"].ToString().Split('.');
docName = docStr[0];
}
if (bytes.Length > 0)
{
//这一步就是具体的格式转制过程(将在下面代码进行分析解释)
putFile(context, bytes, id, ext);
}
else
{
id = "0";
}
result = id + "|" + docName + "|" + submitDate;
这里我们基本上已经完成了一大半了,成功的把数据从数据库中读取出来了,接下来我们就会对这些数据进行相应的解析处理,使它们能够满足我们的需要在页面中进行展示。
//传入四个基本参数
public void putFile
(HttpContext context, byte[] bytes, string id, String ext)
{
try
{
//根据相对路径创建临时文件目录
string savePath = context.Server.MapPath("~/WeekReport/");
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
//向空的文件中写入数据流
using (FileStream fs = new FileStream(savePath + id + ext, FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
}
//使用Aspose.Words的功能配合"Save"进行Word文档到HTML页面的转制工作
Aspose.Words.Document doc = new Aspose.Words.Document(savePath + id + ext);
HtmlSaveOptions hso = new HtmlSaveOptions(SaveFormat.Html);
string htmlPath = savePath + id + ".html";
doc.Save(htmlPath, hso);
//转制完成后,删除原有的Word文件
DeleteFile(savePath + id + ext);
}
catch (Exception ex)
{
throw ex;
}
public static void DeleteFile(string fileUrl)
{
if (System.IO.File.Exists(fileUrl))
{
System.IO.File.Delete(fileUrl);
}
}
}
最后回到前台页面中AJAX这一条语句:
document.getElementById('myFrame').src =
'../WordFile' + dataStr[0] + '.html';
把转制的HTML页面放到IFrame中,这就形成了文档预览。
小结:文档预览我们使用Iframe标签配合Aspose.Word来开发,还是有很多地方高度和宽度不匹配,以及Google不能很好的支持Iframe显示的问题,希望未来能解决。