c#预览office文档最全面的例子

前段时间项目有一个在线预览office文档的需求,做了一个小栗子,和大家一起学习学习!如何实现这个功能呢?我总结了几个方案:

方案一:将需要转换的文档通过office组件转换成html查看

方案二:将需要转换的文档通过office组件转换成pdf查看

方案三:通过在服务器部署微软的office web apps进行文档预览 参考网页:
https://www.cnblogs.com/yanweidie/p/4516164.html

方案四:office 在线预览服务

方案五:使用网上很多收费或者不收费的第三方插件

我使用的是方案一,也试过方案二和方案三,相比而言,转换成html比转换成pdf的效率要快很多,只是页面没有pdf美观,而在服务器部署office web apps配置失败了,所以选择放弃。

以下是方案一的案例:

1.首先引入com组件中office库,然后在程序集扩展中引入word的dll,我本来是想使用.net core做这个在线预览offce文档,结果发现.net core 并没有office库,可能是我没有找到

值得注意的是,虽然项目里引入office库,但运行项目后,发现会遇到各种问题,原因是office库并没有你电脑的office应用匹配,所以需要在电脑需要部署office插件

1.行栏中输入命令:dcomcnfg,打开组件服务管理窗口,组件服务->我的电脑->DCOM配置
2.找到Microsoft Excel Application 设置属性标识:交互式用户,在安全了的三个配置全选自定义配置,添加Everyone 组,给这个组的权限都勾选未允许,
3.再找到 Microsoft PowerPoint 幻灯片 权限设置和第二步一样
4.再找到Microsoft Word 97 - 2003 文档 权限设置和第二步一样 (可能office版本不同)
5.在项目的webconfig 里 下 添加 , userName、password为服务器的对应账号密码

查了很多资料,亲测可用 参考网页:https://www.cnblogs.com/5426z/articles/4865312.html

2.预览Excel

        /// 预览Excel
        /// 
        /// 解码的地址
        /// 
        public string PreviewExcel(string physicalPath, string url)
        {
            var resultUrl = string.Empty;
            var serverUrl = string.Empty;
            try
            {
                Microsoft.Office.Interop.Excel.Application application = null;
                //参数
                Workbook workbook = null;
                application = new Microsoft.Office.Interop.Excel.Application();
                object missing = Type.Missing;
                object trueObject = true;
                application.Visible = false;
                application.DisplayAlerts = false;
                workbook = application.Workbooks.Open(physicalPath, missing, trueObject, missing, missing, missing,
                   missing, missing, missing, missing, missing, missing, missing, missing, missing);
                object format = XlFileFormat.xlHtml;
                string htmlName = Path.GetFileNameWithoutExtension(physicalPath) + ".html";
                String outputFile = Path.GetDirectoryName(physicalPath) + "\\" + htmlName;
                workbook.SaveAs(outputFile, XlFileFormat.xlHtml, null, null, false, false,
                   XlSaveAsAccessMode.xlNoChange, null, null, null, null, null);

                workbook.Close();
                application.Quit();
                resultUrl = Path.GetDirectoryName(url) + "\\" + htmlName;
                var lastUrl = Path.GetFileName(resultUrl);
                resultUrl = ConfigurationManager.AppSettings["ResultUrl"] + lastUrl;
                serverUrl = ConfigurationManager.AppSettings["ServerUrl"];
            }
            catch (Exception ex)
            {
                this.Write(ex);
            }
            return serverUrl + resultUrl;
}

4.预览Word

>         /// 预览Word(HtmL类型)
>         /// 
>         /// 
>         /// 
>         /// 
>         public string PreviewWord(string physicalPath, string url)
>         {
> 
>             var resultUrl = string.Empty;
>             var serverUrl = string.Empty;
>             object outputFile1 = new object();
>             object missing1 = new object();
>             //检查doc 是否被实例化
>             var idd = 0;
>             var ss = 1;
>             try
>             {
>                 Microsoft.Office.Interop.Word._Application application = null;
>                 Microsoft.Office.Interop.Word._Document doc = null;
>                 application = new Microsoft.Office.Interop.Word.Application();
>                 //参数
>                 object missing = Missing.Value;
>                 object trueObject = true;
>                 application.Visible = false;
>                 application.DisplayAlerts = WdAlertLevel.wdAlertsNone;
>                 object physicalPathObj = physicalPath;
>                 //实例化
>                 doc = application.Documents.Open(ref physicalPathObj, ref missing, ref trueObject, ref missing, ref missing, ref missing,
>                  ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref
> missing);
>                 string htmlName = Path.GetFileNameWithoutExtension(physicalPath) + ".html";
>                 object outputFile = Path.GetDirectoryName(physicalPath) + "\\" + htmlName;
>                 object format = WdSaveFormat.wdFormatHTML;
>                 outputFile1 = outputFile;
>                 missing1 = missing;
>                 idd = doc.DocID;
>                 ss = doc.CompatibilityMode;
>                 //转换并保存
>                 doc.SaveAs(ref outputFile, ref format, ref missing, ref missing, ref missing,
>                                   ref missing, XlSaveAsAccessMode.xlNoChange, ref missing,
>                                   ref missing, ref missing, ref missing, ref missing);
>                 doc.Close();
>                 application.Quit();
>                 //返回137的路径
> 
>                 resultUrl = Path.GetDirectoryName(url) + "\\" + htmlName;
>                 var lastUrl = Path.GetFileName(resultUrl);
>                 resultUrl = ConfigurationManager.AppSettings["ResultUrl"] + lastUrl;
>                 serverUrl = ConfigurationManager.AppSettings["ServerUrl"];
>             }
>             catch (Exception ex)
>             {
>                 this.Write(ex, $"{outputFile1}+{missing1}+{idd.ToString()}+{ss.ToString()}+{physicalPath}");
> 
>             }
>             return serverUrl + resultUrl; }

5.预览ppt,我使用的是Presentation库

  #region  预览ppt(使用Presentation插件)
        /// 
        /// ppt转html
        /// 
        /// 
        public string PptToHtml(string url)
        {
            var resultUrl = string.Empty;
            var serverUrl = string.Empty;
            string htmlName = Path.GetFileNameWithoutExtension(url) + ".html";
            String outputFile = Path.GetDirectoryName(url) + "\\" + htmlName;
            //实例化Presentation类,加载文件
            Spire.Presentation.Presentation ppt = new Spire.Presentation.Presentation();
            try
            {
                //打开文件
                ppt.LoadFromFile(url);
                //保存文件为HTML
                ppt.SaveToFile(outputFile, FileFormat.Html);
            }`在这里插入代码片`
            catch (Exception ex)
            {
                this.Write(ex);
            }
            //得到返回的html地址
            resultUrl = Path.GetDirectoryName(url) + "\\" + htmlName;
            var lastUrl = Path.GetFileName(resultUrl);
            resultUrl = ConfigurationManager.AppSettings["ResultUrl"] + lastUrl;
            serverUrl = ConfigurationManager.AppSettings["ServerUrl"];
            return serverUrl + resultUrl;


        }

6.将需要预览的文档转换成html流后下载到服务器,进行预览,因为浏览器不支持预览本地的文件。

 #region  Http下载文件
        /// 
        /// Http下载文件(返回保存路劲)
        /// 
        /// 下载的oss路径
        public async Task<Result> HttpDownloadFile(string url)
        {
            var result = new Result();
            var urlSpilt = string.Empty;
            var dataNow = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            if (url.IndexOf('?') > 0)
                urlSpilt = url.Substring(0, url.IndexOf('?'));
            var urlStr = Path.GetFileName(urlSpilt);
            var key = ConfigurationManager.AppSettings["UrlKey"];
            //路径
            string path = key + dataNow + urlStr;
            try
            {
                // 设置参数
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream responseStream = response.GetResponseStream();
                //创建本地文件写入流
                Stream stream = new FileStream(path, FileMode.Create);
                byte[] bArr = new byte[1024];
                int size = await responseStream.ReadAsync(bArr, 0, (int)bArr.Length);
                while (size > 0)
                {
                    stream.Write(bArr, 0, size);
                    size = await responseStream.ReadAsync(bArr, 0, (int)bArr.Length);
                }
                stream.Close();
                responseStream.Close();
                result.Url = path;
                result.IsSuccure = true;
            }
            catch (Exception ex)
            {
                this.Write(ex);
                result.IsSuccure = false;
                result.Message = "操作失败,请检查文件路径及文件格式是否正确";
            }
            return result;
        }
        #endregion

7.错误日志

       /// 错误日志
        /// 
        /// 
        /// 打印其他信息,看插件是否实例化
        public void Write(Exception ex, string message = "")
        {
            var SaveKey = ConfigurationManager.AppSettings["UrlKey"];
            string filePath = SaveKey + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
            FileStream fs = System.IO.File.Create(filePath);
            StreamWriter sw = new StreamWriter(fs);
            //开始写入
            sw.WriteLine("异常信息=" + ex.Message);
            sw.WriteLine(ex.StackTrace);
            sw.WriteLine($"自定义消息:{message}");
            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();
        }
复制代码

8.返回在服务器上已经转换成功的html文件路径

  /// 返回最终结果的html
    /// 
    /// oss路径
    public async Task<Result> GetResultUrl(string url)
    {
        var SaveKey = ConfigurationManager.AppSettings["UrlKey"];
        Result result = new Result();
        Helper helper = new Helper();
        try
        {
            string physicalPath = Server.UrlDecode(url);
            //去除url后的参数
            if (physicalPath.IndexOf('?') > 0)
                physicalPath = physicalPath.Substring(0, physicalPath.IndexOf('?'));
            string extension = Path.GetExtension(physicalPath);
            switch (extension.ToLower())
            {
                case ".xls":
                case ".xlsx":
                    var resultPathExel = await helper.HttpDownloadFile(url);
                    if (resultPathExel != null && !resultPathExel.IsSuccure)
                    {
                        result.IsSuccure = false;
                        result.Message = resultPathExel.Message;
                        return result;
                    }
                    //转换成html流
                    string physicalPath1 = Server.UrlDecode(resultPathExel.Url);
                    result.Url =  helper.PreviewExcel(physicalPath1, resultPathExel.Url);
                    result.State = (int)Etype.Html;
                    result.IsSuccure = true;
                    break;
                case ".doc":
                case ".docx":
                    var resultPathWord = await helper.HttpDownloadFile(url);
                    if (resultPathWord != null && !resultPathWord.IsSuccure)
                    {
                        result.IsSuccure = false;
                        result.Message = resultPathWord.Message;
                        return result;
                    }
                    //转换成html流
                    string physicalPath2 = Server.UrlDecode(resultPathWord.Url);
                    result.Url = helper.PreviewWord(physicalPath2, resultPathWord.Url);
                    result.State = (int)Etype.Html;
                    result.IsSuccure = true;
                    break;
                case ".ppt":
                case ".pptx":
                    var resultPathPPT = await helper.HttpDownloadFile(url);
                    if (resultPathPPT != null && !resultPathPPT.IsSuccure)
                    {
                        result.IsSuccure = false;
                        result.Message = resultPathPPT.Message;
                        return result;
                    }
                    string physicalPath3 = Server.UrlDecode(resultPathPPT.Url);
                    result.Url =  helper.PptToHtml(physicalPath3);
                    result.State = (int)Etype.Html;
                    result.IsSuccure = true;
                    break;
                case ".txt":
                    result.Url = url;
                    result.State = (int)Etype.Html;
                    result.IsSuccure = true;
                    break;
                case ".pdf":
                    var resultFile = await helper.HttpDownloadFile(url);
                    if (resultFile != null && !resultFile.IsSuccure)
                    {
                        result.IsSuccure = false;
                        result.Message = resultFile.Message;
                        return result;
                    }
                    //截取web后的地址
                    var urlStr = Path.GetFileName(resultFile.Url);
                    result.Url = urlStr;
                    result.State = (int)Etype.pdf;
                    result.IsSuccure = true;
                    break;
                case ".jpg":
                case ".jpeg":
                case ".bmp":
                case ".gif":
                case ".png":
                    result.Url = url;
                    result.State = (int)Etype.Html;
                    result.IsSuccure = true;
                    break;
                default:
                    result.Url = url;
                    result.State = (int)Etype.other;
                    result.IsSuccure = true;
                    break;
            }
        }
        catch (Exception ex)
        {
            helper.Write(ex);
        }

        return result;
    }

9.在页面预览

   /// 首页
    /// 
    /// 文件网络地址
    /// 
    public async Task<ActionResult> Index(string fileurl)
    {
        Helper helper = new Helper();
        var serverUrl = ConfigurationManager.AppSettings["ServerUrl"];
        string viewUrl = string.Empty;
        var result = new Result();
        if (string.IsNullOrEmpty(fileurl))
        {
            result.IsSuccure = false;
            result.Message = "请输入需要预览的文件地址";
            return Json(result, JsonRequestBehavior.AllowGet);
        }
        //压缩包提示解压
        if (fileurl.IndexOf('?') > 0)
            fileurl = fileurl.Substring(0, fileurl.IndexOf('?'));
        string extension = Path.GetExtension(fileurl);
        if (extension == ".zip")
        {
            result.IsSuccure = false;
            result.Message = "不能预览压缩包文件,请解压后查看";
            return Json(result, JsonRequestBehavior.AllowGet);
        }//得到最终链接地址
        result = await GetResultUrl(fileurl);
        if (result.IsSuccure)
        {
            if (result.State == (int)Etype.Html)
                Response.Redirect(result.Url.ToString());
            if (result.State == (int)Etype.pdf)
                //pdf.js固定的位置
                Response.Redirect($"{serverUrl}Content/web/viewer.html?file=Files/{ result.Url}");
        }
        return View(result);
    }

写在最后的话:

虽然pdf文件可以在谷歌内核打开,但是其他的浏览器是不可以 的比如QQ浏览器,同时我也需要兼容手机端,所以我吧谷歌使用的pdf.js插件搞了过来,大家可以学习一下这个插件,将这个插件部署在自己的项目中,就拥有了谷歌同样预览pdf文件的功能了。

参考资料:https://blog.csdn.net/AresonZ/article/details/81873509

这个小栗子的弊端是不能很多个文件同时预览,会很耗服务器资源,后来我进行了优化,加了冥等性和锁,同时也加了多线程。总之,第一次写博客,和大家交流学习一下,有什么不对的地方希望大家指出。

你可能感兴趣的:(.net,c#,asp.net,后端,https,经验分享)