.net 在線預覽文檔非常全面的案例


前段時間項目有一個在線預覽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  里   <system.web> 下 添加   <identity impersonate="true" userName="Administrator" password="123456"/>  userName、password為服務器的對應賬號密碼

查了很多資料,親測可用  參考網頁:https://www.cnblogs.com/5426z/articles/4865312.html

2.預覽Excel

        /// 預覽Excel
        /// </summary>
        /// <param name="physicalPath">解碼的地址</param>
        /// <param name="url"></param>
        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類型)
        /// </summary>
        /// <param name="physicalPath"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        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插件)
        /// <summary>
        /// ppt轉html
        /// </summary>
        /// <returns></returns>
        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下載文件
        /// <summary>
        /// Http下載文件(返回保存路勁)
        /// </summary>
        /// <param name="url">下載的oss路徑</param>
        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.錯誤日志

        /// 錯誤日志
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="message">打印其他信息,看插件是否實例化</param>
        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
        /// </summary>
        /// <param name="url">oss路徑</param>
        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.在頁面預覽

        /// 首頁
        /// </summary>
        /// <param name="fileurl">文件網絡地址</param>
        /// <returns></returns>
        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

這個小栗子的弊端是不能很多個文件同時預覽,會很耗服務器資源,后來我進行了優化,加了冥等性和鎖,同時也加了多線程。總之,第一次寫博客,和大家交流學習一下,有什么不對的地方希望大家指出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM