现在的位置: 首页 > 综合 > 正文

Office 2003 PIA编程的问题:文件保存为XlFileFormat.xlExcel7格式时Range.Merge()失效

2012年09月15日 ⁄ 综合 ⁄ 共 2497字 ⁄ 字号 评论关闭

先抱怨一下:最近在写一个极其恶心的程序:生成Excel reporting。说这个程序恶心,是因为,实现这个报表的方法有很多,我却不得不用我心目中最差的一种方式来实现。

先说说我心目中最好的方式:应该是用NPOI这样的开源库来实现。这个开源库可以脱离开Office软件来独立地生成Excel文件(包括.xls格式和.xlsx格式)。其实实现这种功能的开源库很多,为什么用NPOI呢?因为:

  • NPOI经无数实践所检验,稳定可靠、兼容性良好;
  • NPOI基于Apache 2.0 License,可以合法且免费地用于商业闭源项目。

但是,因为在这个项目里能说得上话的领导要求不使用任何第三方库,那么我的选择就只有用Office PIA了。这种方式在我心目中是最差解决方案。Office PIA实际上是通过interop的COM组件来调用Office软件本身来实现文件的创建、读取,微软在MSDN里面明明白白地建议开发者:如果想要调用Office 2007,那么就要用Office 2007 PIA。如果想要调用Office 2010软件,那么就要用Office 2010 PIA。这下问题来了:用户的电脑上面部署什么软件,我们是很难控制的——当然我们也可以提要求,要求用户安装什么软件。用户的电脑可能安装Office
2003,也可能安装Office 2007,也可能安装Office 2010,也可能根本没有安装Office。

好吧,现在让我们假设用户的电脑上一定装有Office,但是我们需要兼容Office 2003、Office 2007、Office 2010,那么我们该用哪个版本的Office PIA呢?根据MSDN上的建议,我应该安装最低版本的,Office 2003 PIA。

现在我的问题来了:

先看一下我要实现的效果:

首先我引用了Office 2003 PIA里面的Microsoft.Office.Interop.Excel.dll,然后在命名空间引用里面援引了以下namespace:

using Excel = Microsoft.Office.Interop.Excel;

我规定了文件保存的格式:

/// <summary>Default Excel document file format</summary>
private const Excel.XlFileFormat DefaultFileFormat = Excel.XlFileFormat.xlExcel7;

为了实现单元格合并,我调用了以下语句:

/// <summary>
/// Gets current Worksheet instance.
/// </summary>
public Excel.Worksheet CurrentWorksheet { get; private set; }

/// <summary>
/// Gets current range instance.
/// </summary>
public Excel.Range CurrentRange { get; private set; }

/// <summary>
/// Set current range as specific address in current worksheet.
/// Notice: the range address should be provided as string "$E$2:$G$7" or "E2:G7"
/// </summary>
/// <param name="address">range address</param>
public void SetCurrentRange(string address)
{
    this.CurrentRange = 
        !string.IsNullOrEmpty(address) ? 
        this.CurrentWorksheet.get_Range(address) : 
        this.CurrentWorksheet.Cells;
}

/// <summary>
/// Merge cells in specific range.
/// </summary>
/// <param name="address">range address</param>
public void MergeRange(string address)
{
    this.SetCurrentRange(address);
    this.CurrentRange.Merge();
}

我还用了以下函数来使单元格里面的文字纵向居中:

/// <summary>
/// Set range vertical alignment to be Center.
/// </summary>
public void SetRangeAlign_VerticalCenter()
{
    this.CurrentRange.HorizontalAlignment = Excel.Constants.xlGeneral;
    this.CurrentRange.VerticalAlignment = Excel.Constants.xlCenter;
}

结果看到的结果如下所示:

这个效果有两个问题:

  1. Merge()没有起作用;
  2. 单元格B2里面的文字纵向是顶对齐的,不是居中的。

于是在网上一通海查,尝试代码无数,无果。

经过我不懈的努力,发现:如果将文件保存格式设为 XlFileFormat.xlExcel8,那么一切都正常了:

/// <summary>Default Excel document file format</summary>
private const Excel.XlFileFormat DefaultFileFormat = Excel.XlFileFormat.xlExcel8;

在这里用到了一个枚举值:XlFileFormat.xlExcel8

令我纠结万分的是:XlFileFormat.xlExcel8 是从Office 2007开始才出现的一个枚举值。我先前引用的Office PIA的版本是2003,所以 XlFileFormat.xlExcel8 是无法编译通过的。

当然如果引用Office 2007 PIA,则编译可通过。

看来我将不得不放弃对Office 2003 Application的支持?

抱歉!评论已关闭.