欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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控件

WinForm中如何预览Office文件

3. 编辑wpf用户控件

<usercontrol ...
       ...>
  <grid>
    <documentviewer x:name="documentviewer"/>
  </grid>
</usercontrol>

vs设计预览显示效果如下:

WinForm中如何预览Office文件

如果不需要自带的工具栏, 可以添加以下资源隐藏工具栏:

<!--隐藏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中如何预览Office文件

在winform上添加elementhost

WinForm中如何预览Office文件

将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文件.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。