WinForm中如何预览Office文件
程序员文章站
2022-03-27 08:20:56
本文为大家分享了winform预览office文档的方法,供大家参考,具体内容如下
使用winform, wpf, office组件
原理:使用office com...
本文为大家分享了winform预览office文档的方法,供大家参考,具体内容如下
使用winform, wpf, office组件
原理:使用office com组件将word,excel转换为xps文档, 将wpf的documentviewer控件寄宿到winform中, 实现预览.
1. 新建winform项目
2. 新建wpf用户控件, 注意是wpf控件
3. 编辑wpf用户控件
<usercontrol ... ...> <grid> <documentviewer x:name="documentviewer"/> </grid> </usercontrol>
vs设计预览显示效果如下:
如果不需要自带的工具栏, 可以添加以下资源隐藏工具栏:
<!--隐藏documentviewer边框--> <usercontrol.resources> <style x:key="{x:type documentviewer}" targettype="{x:type documentviewer}"> <setter property="foreground" value="{dynamicresource {x:static systemcolors.windowtextbrushkey}}" /> <setter property="background" value="{dynamicresource {x:static systemcolors.controlbrushkey}}" /> <setter property="focusvisualstyle" value="{x:null}" /> <setter property="template"> <setter.value> <controltemplate targettype="{x:type documentviewer}"> <border borderthickness="{templatebinding borderthickness}" borderbrush="{templatebinding borderbrush}" focusable="false"> <grid keyboardnavigation.tabnavigation="local"> <grid.background> <solidcolorbrush color="{dynamicresource controllightcolor}" /> </grid.background> <grid.rowdefinitions> <rowdefinition height="auto" /> <rowdefinition height="*" /> <rowdefinition height="auto" /> </grid.rowdefinitions> <scrollviewer grid.row="1" cancontentscroll="true" horizontalscrollbarvisibility="auto" x:name="part_contenthost" istabstop="true"> <scrollviewer.background> <lineargradientbrush endpoint="0.5,1" startpoint="0.5,0"> <gradientstop color="{dynamicresource controllightcolor}" offset="0" /> <gradientstop color="{dynamicresource controlmediumcolor}" offset="1" /> </lineargradientbrush> </scrollviewer.background> </scrollviewer> </grid> </border> </controltemplate> </setter.value> </setter> </style> </usercontrol.resources>
4. 新建winform用户控件
在winform上添加elementhost
将wpf用户控件添加到elementhost上,设计器代码xpspreviewer.designer.cs如下
//elementhost private system.windows.forms.integration.elementhost elementhost1; //xpspreviewer变量 private wpf.xpspreviewer xpspreviewer1; private void initializecomponent() { this.elementhost1 = new system.windows.forms.integration.elementhost(); this.xpspreviewer1 = new wpf.xpspreviewer(); //初始化 //其他属性初始化... this.elementhost1.child = this.xpspreviewer1; //其他属性初始化... }
在xpspreviewer.cs后台代码中定义方法:
/// <summary> /// 加载xps文件 /// </summary> /// <param name="filename">xps文件名</param> internal void loadxps(string filename) { var xpsdocument = new xpsdocument(filename, fileaccess.read); this.xpspreviewer1.documentviewer.document = xpsdocument.getfixeddocumentsequence(); xpsdocument.close(); }
5. 将excel(word类似)转换为xps文件
通过nuget包管理控制台安装com组件:
pm> install-package microsoft.office.interop.excel
转换为xps:
/// <summary> /// 将excel文件转换为xps文件 /// </summary> /// <param name="execelfilename">excel文件名</param> /// <param name="xpsfilename">转换的xps文件名</param> public void convertexceltoxps(string excelfilename, string xpsfilename) { if (string.isnullorwhitespace(excelfilename)) throw new argumentnullexception(excelfilename); if (string.isnullorwhitespace(xpsfilename)) throw new argumentnullexception(xpsfilename); var fileinfo = new fileinfo(xpsfilename); if (!fileinfo.directory.exists) fileinfo.directory.create(); //删除已存在的文件 if (file.exists(xpsfilename)) file.delete(xpsfilename); excel.application app = new excel.application(); app.displayalerts = false; excel.workbooks wbs; excel.workbook wb; wbs = app.workbooks; wb = wbs.add(excelfilename); dynamic nothing = system.reflection.missing.value; wb.exportasfixedformat(excel.xlfixedformattype.xltypexps, xpsfilename, nothing, nothing, nothing, nothing, nothing, nothing, nothing); wb.close(true); wbs.close(); app.quit(); killexcelprocess(app); }
扩展: 每次调用excel打开文件,均会产生一个进程, 在网络上收集的释放excel进程方式均不起作用. 因此选择直接结束进程, 根据excel句柄结束进程, 而不是根据进程名称杀死全部正在运行的excel.
[dllimport("user32.dll")] private static extern int getwindowthreadprocessid(intptr hwnd, out int processid); /// <summary> /// 结束excel进程 /// </summary> /// <param name="obj"></param> private void killexcelprocess(excel.application app) { if (app == null) return; try { intptr intptr = new intptr(app.hwnd); int id; getwindowthreadprocessid(intptr, out id); var p = process.getprocessbyid(id); p.kill(); } catch { } }
现在已经可以正常的预览excel文件了. 由于excel另存为xps文件会耗费一定的时间, 因此建议在后台线程中提前异步生成, 在预览时可直接调取xps文件.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 转:PHP调试错误