MVC 附件在線預覽

緣由:應客戶需求,在系統中瀏覽附件內容,須要先下載到本地而後打開,對使用形成了不便,要求能夠不需下載直接在瀏覽器中打開減小操做步驟。javascript

領導給了3天時間,最後查找方法,寫測試項目,往正式項目添加,測試,修bug,優化下來總共花費了大概兩天多時間。下面給出解決經驗,主要把遇到的坑html

給說一下。java

1.研究方案web

參考:http://www.cnblogs.com/xuse/p/3710647.html瀏覽器

使用FlexPaper實現office文件的預覽(C#版)
http://www.cnblogs.com/zzPrince/p/3378336.html服務器

flexpaper使用:app

http://www.cnblogs.com/Gnepner/archive/2011/08/19/2145493.htmlasp.net

經過研究發現,網上流傳不少方法能夠實現該需求,排除第三方控件的話,有兩種比較流行,一種是把文檔轉化爲swf格式,還有一種是轉化爲html實如今線預覽。ide

可是按照網上的原話,轉化爲html方法很不科學,轉換的文件格式丟失,僅限於IIS服務器,利用asp.net。配置麻煩,正如微軟所說,讀取office不是這麼幹的,鑑於此工具

先嚐試另外一種方案。

原理:先將office轉換爲PDF,再轉換爲SWF,最後經過網頁加載Flash預覽。

2.搭建測試項目

2.1工具:

a.安裝Microsoft Office 2007以上版本,主要是須要用到裏面四個類庫,稍後列出。

b.Swftools

下載地址:http://www.swftools.org/download.html

這有個小坑,看好要下載window版。

c.flexpaper

下載地址:http://flexpaper.devaldi.com/download.htm

2.2搭建測試項目

因爲本系統用的是Mvc開發,因此先建了一個MvcTest項目。

添加引用,此處有小坑,注意在引用的類庫上右鍵,把嵌入互操做類型改成False,

引用版本最好12.0.0.0,14.0.0.0經測試也可用,網上說存在權限認證問題。

添加工具,項目文件

a.Common>Utils裏面寫Word,Excel,PPT等轉化爲PDF的方法,網上有不少,主要是Excel的轉化經測試有一些有問題,貼一個靠譜的

 1  public static bool ExcelToPDF(string sourcePath, string targetPath)
 2         {    
 3             bool result = false;
 4             Excel.XlFixedFormatType targetType = Excel.XlFixedFormatType.xlTypePDF;
 5             object missing = Type.Missing;
 6             Excel.ApplicationClass application = null;
 7             Excel.Workbook workBook = null;
 8             try
 9             {
10                 application = new Excel.ApplicationClass();
11                 object target = targetPath;
12                 object type = targetType;
13                 workBook = application.Workbooks.Open(sourcePath, missing, missing, missing, missing, missing,
14                         missing, missing, missing, missing, missing, missing, missing, missing, missing);
15 
16                 workBook.ExportAsFixedFormat(targetType, target, Excel.XlFixedFormatQuality.xlQualityStandard, true, false, missing, missing, missing, missing);
17                 result = true;
18             }
19             catch
20             {
21                 result = false;
22             }
23             finally
24             {
25                 if (workBook != null)
26                 {
27                     workBook.Close(true, missing, missing);
28                     workBook = null;
29                 }
30                 if (application != null)
31                 {
32                     application.Quit();
33                     application = null;
34                 }
35                 GC.Collect();
36                 GC.WaitForPendingFinalizers();
37                 GC.Collect();
38                 GC.WaitForPendingFinalizers();
39             }
40             return result;
41            
42         }
ExcelToPDF

b.修改控制器

先在HomeController控制器的視圖裏裏添加一個連接

<div>
    <input id="fileName" name="fileName" type="text" style="width:100px;"/>
    <a  href="#" onclick="preview();" >預覽</a>
</div>

<script type="text/javascript">
        function preview() {      
            var name=$("#fileName").val();   
            window.open("/Home/Preview?name=" + name);
        }
</script>

再在控制器裏添加一個方法:

        public ActionResult Preview(string name="")
        {
            string url = "/FlexPaper/Index?filePath=~/UploadFiles/" + name;
            return Redirect(url);            
        }

測試用RedirectToAction的方法走不到FlexPaper控制器裏,貌似是路由的問題,爲節省時間直接使用Redirect方法,成功進去了。

而後新建一個FlexPaperController控制器,裏面寫的有本身從網上down的代碼,加上本身的優化,判斷文件是否存在,刪除舊文件,是否可轉化等等提示。

  1 public class FlexPaperController : Controller
  2     {
  3        
  4         string pdf2swfToolPath = System.Web.HttpContext.Current.Server.MapPath("~/FlexPaper/pdf2swf.exe");
  5         string png2swfToolPath = System.Web.HttpContext.Current.Server.MapPath("~/FlexPaper/png2swf.exe");
  6         string jpeg2swfToolPath = System.Web.HttpContext.Current.Server.MapPath("~/FlexPaper/jpeg2swf.exe");
  7         string gif2swfToolPath = System.Web.HttpContext.Current.Server.MapPath("~/FlexPaper/gif2swf.exe");
  8     
  9 
 10         public ActionResult Index(string filePath = "")
 11         {      
 12 
 13             string msg = CreateSWF(filePath);
 14             if (msg == "生成成功")
 15             {
 16                 string FilePath = Server.MapPath(filePath);
 17                 string fileNameWithoutEx = System.IO.Path.GetFileNameWithoutExtension(FilePath);//不包含路徑,不包含擴展名
 18                 string extendName = System.IO.Path.GetExtension(FilePath).ToLower();//文件擴展名
 19                 var sign = extendName.Replace(".", "");
 20 
 21                 string url = "/FlexPaper/SWF/" + fileNameWithoutEx +sign+ ".swf";
 22                 try
 23                 {
 24                     return Redirect(string.Format("/FlexPaper/FlexPaperViewer.html?emotion={0}", url));
 25                 }
 26                 catch
 27                 {
 28                     return Content("轉化失敗,不支持該類型轉化!");
 29                 }
 30             }
 31             else
 32                 return Content(msg);
 33         }
 34 
 35         /// <summary>
 36         /// 0:轉化成功
 37         /// 1:不支持的該Office文件類型到pdf的轉化
 38         /// 2:不支持的該文件類型到swf的轉化
 39         /// </summary>
 40         /// <returns></returns>
 41         public string CreateSWF(string filePath)
 42         {          
 43             string FilePath = Server.MapPath(filePath);
 44             int index = FilePath.LastIndexOf("\\");
 45             string officePath = FilePath.Substring(0, index)+"\\";
 46             string officeName = Server.UrlDecode(FilePath.Substring(index + 1));
 47             string fileNameWithoutEx = System.IO.Path.GetFileNameWithoutExtension(FilePath);//不包含路徑,不包含擴展名
 48             string extendName = System.IO.Path.GetExtension(FilePath).ToLower();//文件擴展名
 49             string sign = extendName.Replace(".", "");
 50             string PdfFilePath = Server.MapPath("~/FlexPaper/PDF/");
 51             string SWFFilePath = Server.MapPath("~/FlexPaper/SWF/");
 52 
 53 
 54             #region delete old file
 55             string oldPdf = PdfFilePath + fileNameWithoutEx + sign + ".pdf";
 56             if (System.IO.File.Exists(oldPdf))
 57             {
 58                 System.IO.File.Delete(oldPdf);
 59             }
 60             string oldSwf = SWFFilePath + fileNameWithoutEx + sign + ".swf";
 61             if (System.IO.File.Exists(oldSwf))
 62             {
 63                 System.IO.File.Delete(oldSwf);
 64             }   
 65             #endregion
 66 
 67             if (!System.IO.File.Exists(FilePath))
 68             {
 69                 return "找不到該文件!" ;
 70             }  
 71 
 72 
 73             if (extendName == ".doc" ||
 74                extendName == ".docx" ||
 75                extendName == ".xls" ||
 76                extendName == ".ppt")
 77             {               
 78                
 79                 //string pdf2swfToolPath = string.Format("{0}\\pdf2swf.exe", Server.MapPath("~/FlexPaper"));
 80 
 81                 string PdfName = Utils.OfficeToPdf(officePath, officeName, PdfFilePath);
 82                 if (PdfName == "")
 83                 {
 84                     return "不支持該Office文件類型到pdf的轉化!";
 85                 }
 86                 string SwfName = Utils.PdfToSwf(pdf2swfToolPath, PdfFilePath, PdfName, SWFFilePath);
 87                 if (SwfName == "")
 88                 {
 89                     return "不支持該文件類型到swf的轉化!";
 90                 }
 91                 return "生成成功";
 92             }
 93             else if (extendName == ".jpg" || extendName == ".jpeg" || extendName == ".png" || extendName == ".gif")
 94             {
 95                 string toolpath = String.Empty;
 96                 switch (extendName)
 97                 {
 98                     case ".jpg":
 99                         toolpath = jpeg2swfToolPath;
100                         break;
101                     case ".jpeg":
102                         toolpath = jpeg2swfToolPath;
103                         break;
104                     case ".png":
105                         toolpath = png2swfToolPath;
106                         break;
107                     case ".gif":
108                         toolpath = gif2swfToolPath;
109                         break;
110                     default:
111                         break;
112                 }
113                 string SwfFileName = Utils.PictureToSwf(toolpath, officePath, officeName, SWFFilePath);
114                 return "生成成功";
115             }
116             else
117                 return "不支持該文件類型的轉化!";
118         }
FlexPaperController

c.新建FlexPaper文件夾,在該文件夾下再另外建立PDF,SWF子文件夾,此處原創便於區分,另把從網上下載demo裏的js,FlexPaperViewer.html,FlexPaperViewer.swf

playerProductInstall.swf文件都拷過去。

把Swftools安裝路徑下的工具pdf2swf.exe,也拷過去,若有須要,其餘類型也可拷過去。

修改FlexPaperViewer.html便於傳遞文件名

<script type="text/javascript">
            //得到參數的方法
            var request =
            {
                QueryString: function (val) {
                    var uri = window.location.search;
                    var re = new RegExp("" + val + "=([^&?]*)", "ig");
                    return ((uri.match(re)) ? (uri.match(re)[0].substr(val.length + 1)) : null);
                }
            }
</script> 


   var emotion = request.QueryString('emotion'); ; //這填寫文檔轉成的flash文件路徑
   var swfFile = emotion;

            var flashvars = {
                  SwfFile: escape(swfFile),//這裏用到swf路徑
	          Scale : 0.6, 
		  ZoomTransition : "easeOut",

UploadFiles裏添加須要在線預覽的office文件。

3.最後一個坑

在本地調試沒有問題,發佈到IIS上後,一直加載中,沒法正常顯示,經查找測試發現是引用office組件的權限問題。

須要在Web.config里加一段代碼:

 <system.web>
    <identity impersonate="true" userName="你的用戶名" password="密碼"/>

4.預覽效果

相關文章
相關標籤/搜索