MVC 附件在线预览

原因:应客户需求,在系统中浏览附件内容,需要先下载到本地然后打开,对使用造成了不便,要求可以不需下载直接在浏览器中打开减少操作步骤。

领导给了3天时间,最后查找方法,写测试项目,往正式项目添加,测试,修bug,优化下来总共花费了大概两天多时间。下面给出解决经验,主要把遇到的坑

给说一下。

1.研究方案

参考:http://www.cnblogs.com/xuse/p/3710647.html

使用FlexPaper实现office文件的预览(C#版)
http://www.cnblogs.com/zzPrince/p/3378336.html

flexpaper使用:

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

通过研究发现,网上流传很多方法可以实现该需求,排除第三方控件的话,有两种比较流行,一种是把文档转化为swf格式,还有一种是转化为html实现在线预览。

但是按照网上的原话,转化为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.预览效果

 

posted on 2015-01-16 17:31  Cloud.Yt  阅读(1132)  评论(1编辑  收藏  举报