CefSharp中实现Chrome中jS导出Excel
【前言】
在博客园闲逛了一年多,平时都是借鉴别人的成功经验,总觉得自己应该分享点什么,但是苦于自己技术有限,平时又不爱写东西,所以一直没有写过任何东西。毕业一年多,在现实工作中遇到各种问题,深切体会到遇到问题时的焦急与纠结。今天决定写自己的第一篇现实中遇到的问题。希望能够为遇到类似问题的博友们提供一些帮助。文章可能写的不好,请勿喷!!
【背景】
使用JS将<table>数据以Excel形式已经不是新鲜事情,在IE中常常使用ActiveXObject来创建Excel.application对象来处理。但是Chrome里面并不支持创建ActiveXObject对象方式来进行处理,所以有人在Chrome里面使用某种JS来进行处理导出页面table数据,具体方式见山维空间博客。
【环境】
先说一下自己参与项目的背景,项目架构是采B/S和C/S的混合架构。业务实现是Java实现,可以通过浏览器访问,但是有一部分功能必须使用.Net实现。所以又采用.Net来做客户端,在客户端中使用内嵌浏览器的方式来实现整体功能。开始客户端使用过webBrowser来作为内嵌浏览器,但是说实话,IE的东西性能太差,兼容性又不好。所以最后决定使用webKit内核的浏览器。最后选择了cefSharp .
【遇到问题】
如果读者没有看山维空间博客的空间,建议先看完该博客再继续看下面。
使用博客中提到的JS实现方式,在Chrome能够实现将页面<table>表格数据以Excel形式导出。但是在CefSharp里面却没有任何反应。跟踪调试发现JS已经执行location.href = uri + base64(template(tables));执行完成后没有任何操作。CefSharp中只能执行到RequestHandler控制类的 OnBeforeResourceLoad方法执行完成就结束。
具体原因未知。
【解决】
查看OnBeforeResourceLoad方法的requestResponse参数能够找到URL就是我们最后传递的数据。最后做了如下操作使得问题解决.
实现OnBeforeBrowse方法,在该方法中做Excel导出:
1 public bool OnBeforeBrowse(IWebBrowser browser, IRequest request, NavigationType naigationvType, bool isRedirect) 2 { 3 if (url.Contains("application/vnd.ms-excel;base64")) 4 { 5 string tmpContent = url;//获取传递上来的文件内容 6 string contentHead = "data:application/vnd.ms-excel;base64,"; 7 int startIndex = tmpContent.IndexOf(contentHead); 8 int name_StartIndex = tmpContent.IndexOf(contentHead) + contentHead.Length; 9 int name_EndIndex = tmpContent.IndexOf('#'); 10 string fileName = "Excel表格"; 11 if (name_EndIndex != -1) 12 { 13 fileName = Uri.UnescapeDataString(tmpContent.Substring(name_StartIndex, name_EndIndex - name_StartIndex)); 14 tmpContent = tmpContent.Substring(name_EndIndex + 1); 15 } 16 else 17 { 18 tmpContent = tmpContent.Substring(name_StartIndex); 19 } 20 byte[] output = Convert.FromBase64String(tmpContent); 21 SaveFileDialog dialog = new SaveFileDialog(); 22 dialog.FileName = fileName+".xls"; 23 dialog.Filter = "(Excel文件)|*.xls"; 24 DialogResult result = dialog.ShowDialog(); 25 if (result == DialogResult.OK) 26 { 27 using (FileStream fs = new FileStream(dialog.FileName, FileMode.Create, FileAccess.Write)) 28 { 29 fs.Write(output, 0, output.Length); 30 fs.Flush(); 31 } 32 return true; 33 } 34 } 35 return false; 36 }
使得该功能能够正常实现。如果你有更好的实现方式,欢迎一起交流!!