欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET实现在网页中预览Office文件的3个方法

程序员文章站 2024-02-24 08:12:40
近日公司要搞一个日常的文档管理的东东,可以上传、下载各种文件,如果是office文件呢还必须得支持预览功能,其他的都好说但是唯独office预览功能比较麻烦,但是不能不做,...

近日公司要搞一个日常的文档管理的东东,可以上传、下载各种文件,如果是office文件呢还必须得支持预览功能,其他的都好说但是唯独office预览功能比较麻烦,但是不能不做,废话不多说了一步步来吧。分析了下网易邮箱的文件预览功能,他用的是微软的组件,最早叫office online,现在分开了叫word online、excel online ....等等,效果十分炫酷功能十分强大,但是查看了下对api的说明发现对服务器的要求比较苛刻而且配置比较复杂不太适合。然后 又看了下腾讯用的是永中第三方组件,效果嘛自然比不上微软的但是能用,综合网上的一些资料大概也就那么几种方式实现

1.使用microsoft的office组件将文件直接转换为html文件(优点:代码实现最简单,工作强度最小。缺点:效果极差)

2.使用microsoft的office组件将文件转换为pdf格式文件,然后再使用pdf2swf转换为swf文件,也就是flash文件在使用flexpaper展示出来(优点:预览效果能接受,缺点:代码量大)

效果如图:

.NET实现在网页中预览Office文件的3个方法

3. 使用office online(优点:表现完美,缺点:不适合中小企业应用)

综合考虑决定使用第二种方法,经过次次波折终于可以使用,但是有个问题至今没有得到解决,调用office组件的时候有时候会出现如下异常:

检索 com 类工厂中 clsid 为 {000209ff-0000-0000-c000-000000000046} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。 (异常来自 hresult:0x8000401a),查阅无数资料还是不能解决,最让人不可接受的的是office文件必须标标准准毫无容错能力,当转换ppt文件时竟然会弹出转换进度框!!

好吧!那么我们改进它。

使用aspose+pdf2swf+flexpaper

关于aspose大家可以到官网了解,这是款商业收费产品但是免费也可以使用

1、引用dll

.NET实现在网页中预览Office文件的3个方法

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生成预览文件是个耗时的操作,

文件越大耗时越长,也就是说生成预览文件的时候是需要时间的,因此我使用异步方式生成预览文件。