.NET实现在网页中预览Office文件的3个方法
近日公司要搞一个日常的文档管理的东东,可以上传、下载各种文件,如果是office文件呢还必须得支持预览功能,其他的都好说但是唯独office预览功能比较麻烦,但是不能不做,废话不多说了一步步来吧。分析了下网易邮箱的文件预览功能,他用的是微软的组件,最早叫office online,现在分开了叫word online、excel online ....等等,效果十分炫酷功能十分强大,但是查看了下对api的说明发现对服务器的要求比较苛刻而且配置比较复杂不太适合。然后 又看了下腾讯用的是永中第三方组件,效果嘛自然比不上微软的但是能用,综合网上的一些资料大概也就那么几种方式实现
1.使用microsoft的office组件将文件直接转换为html文件(优点:代码实现最简单,工作强度最小。缺点:效果极差)
2.使用microsoft的office组件将文件转换为pdf格式文件,然后再使用pdf2swf转换为swf文件,也就是flash文件在使用flexpaper展示出来(优点:预览效果能接受,缺点:代码量大)
效果如图:
3. 使用office online(优点:表现完美,缺点:不适合中小企业应用)
综合考虑决定使用第二种方法,经过次次波折终于可以使用,但是有个问题至今没有得到解决,调用office组件的时候有时候会出现如下异常:
检索 com 类工厂中 clsid 为 {000209ff-0000-0000-c000-000000000046} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。 (异常来自 hresult:0x8000401a),查阅无数资料还是不能解决,最让人不可接受的的是office文件必须标标准准毫无容错能力,当转换ppt文件时竟然会弹出转换进度框!!
好吧!那么我们改进它。
使用aspose+pdf2swf+flexpaper
关于aspose大家可以到官网了解,这是款商业收费产品但是免费也可以使用
1、引用dll
2、编写转换帮助类
using system;
using system.collections.generic;
using system.linq;
using system.text;
using aspose.cells;
using aspose.words;
using aspose.slides;
using system.text.regularexpressions;
using system.io;
namespace souxuexiao.common
{
/// <summary>
/// 第三方组件aspose office/wps文件转换
/// writer:helen joe
/// date:2014-09-24
/// </summary>
public class asposeutils
{
/// <summary>
/// pfd转换器位置
/// </summary>
private static string _exefilename = system.web.httpcontext.current != null
? system.web.httpcontext.current.server.mappath("/pdf2swf/pdf2swf.exe")
: system.io.path.combine(appdomain.currentdomain.basedirectory + "\\pdf2swf\\pdf2swf.exe");
#region 1.01 wrod文档转换为pdf文件 +convertdoctopdf(string sourcefilename, string targetfilename)
/// <summary>
/// wrod文档转换为pdf文件
/// </summary>
/// <param name="sourcefilename">需要转换的word全路径</param>
/// <param name="targetfilename">目标文件全路径</param>
/// <returns>转换是否成功</returns>
public static bool convertdoctopdf(string sourcefilename, string targetfilename)
{
souxuexiao.api.logger.error(string.format("wrod文档转换为pdf文件:sourcefilename={0},targetfilename={1}", sourcefilename, targetfilename));
try
{
using (system.io.stream stream = new system.io.filestream(sourcefilename, system.io.filemode.open, system.io.fileaccess.read, system.io.fileshare.readwrite))
{
document doc = new document(sourcefilename);
doc.save(targetfilename, aspose.words.saveformat.pdf);
}
}
catch (exception ex)
{
souxuexiao.api.logger.error(string.format("wrod文档转换为pdf文件执行convertdoctopdf发生异常原因是:{0}",ex.message));
}
return system.io.file.exists(targetfilename);
}
#endregion
#region 1.02 excel文件转换为html文件 +(string sourcefilename, string targetfilename, string guid)
/// <summary>
/// excel文件转换为html文件
/// </summary>
/// <param name="sourcefilename">excel文件路径</param>
/// <param name="targetfilename">目标路径</param>
/// <returns>转换是否成功</returns>
public static bool convertexceltohtml(string sourcefilename, string targetfilename)
{
souxuexiao.api.logger.info(string.format("准备执行excel文件转换为html文件,sourcefilename={0},targetfilename={1}",sourcefilename,targetfilename));
try
{
using (system.io.stream stream = new system.io.filestream(sourcefilename, system.io.filemode.open, system.io.fileaccess.read, system.io.fileshare.readwrite))
{
aspose.cells.workbook workbook = new workbook(stream);
workbook.save(targetfilename, aspose.cells.saveformat.html);
}
}
catch (exception ex)
{
souxuexiao.api.logger.error(string.format("excel文件转换为html文件convertexceltohtml异常原因是:{0}", ex.message));
}
return system.io.file.exists(targetfilename);
}
#endregion
#region 1.03 将powerpoint文件转换为pdf +convertpowerpointtopdf(string sourcefilename, string targetfilename)
/// <summary>
/// 将powerpoint文件转换为pdf
/// </summary>
/// <param name="sourcefilename">ppt/pptx文件路径</param>
/// <param name="targetfilename">目标文件路径</param>
/// <returns>转换是否成功</returns>
public static bool convertpowerpointtopdf(string sourcefilename, string targetfilename)
{
souxuexiao.api.logger.info(string.format("准备执行powerpoint转换pdf,sourcefilename={0},targetfilename={1}",sourcefilename,targetfilename));
try
{
using (system.io.stream stream = new system.io.filestream(sourcefilename, system.io.filemode.open, system.io.fileaccess.read, system.io.fileshare.readwrite))
{
aspose.slides.pptx.presentationex pptx = new aspose.slides.pptx.presentationex(stream);
pptx.save(targetfilename, aspose.slides.export.saveformat.pdf);
}
}
catch (exception ex)
{
souxuexiao.api.logger.error(string.format("将powerpoint文件转换为pdfconvertexceltohtml异常原因是:{0}", ex.message));
}
return system.io.file.exists(targetfilename);
}
#endregion
#region 2.01 读取pdf文件的总页数 +getpagecount(string pdf_filename)
/// <summary>
/// 读取pdf文件的总页数
/// </summary>
/// <param name="pdf_filename">pdf文件</param>
/// <returns></returns>
public static int getpagecountbypdf(string pdf_filename)
{
int pagecount = 0;
if (system.io.file.exists(pdf_filename))
{
try
{
byte[] buffer = system.io.file.readallbytes(pdf_filename);
if (buffer != null && buffer.length > 0)
{
pagecount = -1;
string pdftext = encoding.default.getstring(buffer);
regex regex = new regex(@"/type\s*/page[^s]");
matchcollection conllection = regex.matches(pdftext);
pagecount = conllection.count;
}
}
catch (exception ex)
{
souxuexiao.api.logger.error(string.format("读取pdf文件的总页数执行getpagecountbypowerpoint函数发生异常原因是:{0}", ex.message));
}
}
return pagecount;
}
#endregion
#region 2.02 转换pdf文件为swf格式 +pdfconverttoswf(string pdfpath, string swfpath, int page)
/// <summary>
/// 转换pdf文件为swf格式
/// </summary>
/// <param name="pdfpath">pdf文件路径</param>
/// <param name="swfpath">swf生成目标文件路径</param>
/// <param name="page">pdf页数</param>
/// <returns>生成是否成功</returns>
public static bool pdfconverttoswf(string pdfpath, string swfpath, int page)
{
stringbuilder sb = new stringbuilder();
sb.append(" \"" + pdfpath + "\"");
sb.append(" -o \"" + swfpath + "\"");
sb.append(" -z");
//flash version
sb.append(" -s flashversion=9");
//禁止pdf里面的链接
sb.append(" -s disablelinks");
//pdf页数
sb.append(" -p " + "\"1" + "-" + page + "\"");
//swf中的图片质量
sb.append(" -j 100");
string command = sb.tostring();
system.diagnostics.process p = null;
try
{
using (p = new system.diagnostics.process())
{
p.startinfo.filename = _exefilename;
p.startinfo.arguments = command;
p.startinfo.workingdirectory = system.io.path.getdirectoryname(_exefilename);
//不使用操作系统外壳程序 启动 线程
p.startinfo.useshellexecute = false;
//p.startinfo.redirectstandardinput = true;
//p.startinfo.redirectstandardoutput = true;
//把外部程序错误输出写到standarderror流中(pdf2swf.exe的所有输出信息,都为错误输出流,用 standardoutput是捕获不到任何消息的...
p.startinfo.redirectstandarderror = true;
//不创建进程窗口
p.startinfo.createnowindow = false;
//启动进程
p.start();
//开始异步读取
p.beginerrorreadline();
//等待完成
p.waitforexit();
}
}
catch (exception ex)
{
souxuexiao.api.logger.error(string.format("转换pdf文件为swf格式执行pdfconverttoswf函数发生异常原因是:{0}", ex.message));
}
finally
{
if (p != null)
{
//关闭进程
p.close();
//释放资源
p.dispose();
}
}
return file.exists(swfpath);
}
#endregion
}
}
office格式转换
3、将pdf文件转swf的转换器放到站点根目录下新建文件夹pdf2swf(我就是这么配置的,您随意)
4、配置flexpaper
预览页面引用
<script src="/flexpaper/js/swfobject.js" type="text/javascript"></script>
<script type="text/javascript" src="/flexpaper/js/flexpaper_flash.js"></script>
控件容器以及设置项
<div style="margin:0 auto;width:980px;">
<div id="flashcontent" style="display:none;">
<p>
to view this page ensure that adobe flash player version
10.0.0 or greater is installed.
</p>
<script type="text/javascript">
var pagehost = ((document.location.protocol == "https:") ? "https://" : "http://");
document.write("<a href='http://www.adobe.com/go/getflashplayer'><img src='" + pagehost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='get adobe flash player' /></a>");
</script>
</div>
<script type="text/javascript">
var _filename = document.getelementbyid("_filename").value;
var swfversionstr = "9.0.0";
var xiswfurlstr = "playerproductinstall.swf";
var flashvars = {
swffile: escape(_filename),
scale: 0.6,
zoomtransition: "easeout",
zoomtime: 0.5,
zoominterval: 0.1,
fitpageonload: false,
fitwidthonload: true,
printenabled: true,
fullscreenasmaxwindow: false,
progressiveloading: true,
printtoolsvisible: true,
viewmodetoolsvisible: true,
zoomtoolsvisible: true,
fullscreenvisible: true,
navtoolsvisible: true,
cursortoolsvisible: true,
searchtoolsvisible: true,
searchmatchall:true,
localechain: "zh_cn"
};
var params = {
quality: "high",
bgcolor: "#ffffff",
allowscriptaccess: "samedomain",
allowfullscreen: "true"
}
var attributes = { id: "flexpaperviewer", name: "flexpaperviewer" };
swfobject.embedswf("/flexpaper/flexpaperviewer.swf", "flashcontent", "980", "620", swfversionstr, xiswfurlstr, flashvars, params, attributes);
swfobject.createcss("#flashcontent", "display:block;text-align:left;");
</script>
</div>
document.getelementbyid("_filename").value是预览文件的路径
ok 大功告成 ,至于如何上传,怎么保存上传的文件等等那些逻辑我这里就省略了。。。。,但是有个建议,当用户上传文件之后调用转换api生成预览文件是个耗时的操作,
文件越大耗时越长,也就是说生成预览文件的时候是需要时间的,因此我使用异步方式生成预览文件。