`

我在使用 NPOI 时遇到的问题 - Cell Comment

阅读更多

NPOI 版本信息:

Binary: 2.1.3.1

Source Code: https://github.com/tonyqus/npoi (2015-06-15)

 

本期问题:Cell Comment

1. Comment Count

NPOI 限制了每个 HSSFSheet 最大 Comment 数量:1024。(不知道为什么要这么做)(貌似 POI 中已经修复了这个 bug

这会导致:

1.1 如果添加的 Comment 数超过 1024,会引起 NPOI 内部抛出异常 (ArgumentException)。

a) HSSFComment 有个属性 NoteRecord (_note,NPOI.HSSF.Record.NoteRecord),记录了 Comment 的一些信息。

b) HSSFComment 创建后,其属性 ShapeId (int) 会被赋值。

c) 在这个赋值的过程中又会对 NoteRecord 的属性 ShapeId 赋值 (对1024取余的值):

 

public override int ShapeId
{
    get { return base.ShapeId; }
    set
    {
        //...
        _note.ShapeId = (value % 1024);
    }
}
d) NPOI 内部 (EscherAggregate)用 Dictionary 维护这些 NoteRecord。其中 Key 的值是 NoteRecord 的属性 ShapeId。(这就限定了最大数量:1024)。
e) 当把 NoteRecord 添加到 Dictionary(tailRec)中时,会先判断是否已存在相同的 Key。如果已存在,就往 Dictionary 中添加,这就导致抛出异常。(为什么要这么做啊)
internal void AddTailRecord(NoteRecord note)
{
    if (tailRec.ContainsKey(note.ShapeId))
        tailRec.Add(note.ShapeId, note);
    else
        tailRec[note.ShapeId] = note;
}
1.2 如果从现有文件载入 Sheet,且 Sheet 中 Comment 数量超过1024,会导致在取1024前的 Comment 时取到 null,在1024后的 Comment 时拿到的是1024前的某个 Comment。
a) NPOI 载入 Sheet 时会读取所有 NoteRecord(包括其它 Record),存入List。在创建 NoteRecord 实例时,从文件数据流中读取的 ShapeId 可能会重复,即:两个 NoteRecord 有相同的 ShapeId。而且 ShapeId 都是小于 1024 的非负整数。暂时还不了解原因(难道是对文件数据流的解析有问题?)。
b) 首次获取 Cell Comment 时,准确的说是首次创建 HSSFSheet 的 _patriarch (HSSFPatriarch)时,会将这些 NoteRecord 存入 tailRec。此时可能因为 NoteRecord 的 ShapeId 有重复,导致后面添加的项可能会替换之前的项。
c) 创建 HSSFPatriarch 实例的同时,会创建 HSSFComment 实例(HSSFShapeFactory.CreateShapeTree)。此时会根据相应 Record 的数据,从 tailRec 里找到对应的 NoteRecord,并将其传给 HSSFComment 的构造函数。查找 NoteRecord 时是根据 NoteRecord 的 ShapeId 属性进行判断。所以由上一步可知,可能发生 HSSFComment 与 NoteRecord 错乱的情况。
c) 获取某个 Cell 的 Comment 时,会搜索所有 Comment,根据 Cell 的 Row 和 Column 是否与 Comment 的 Row 和 Column 相等。而 Comment 的 Row 和 Column 的值是从它对应的 NoteRecord 的 Row 和 Column 取的。由上一步可知,可能目标的 Comment 无法与该 Cell 匹配,从而得到 null;或其它 Comment 与该 Cell 匹配成功,得到错位的 Comment。
另:XSSF 中处理 Comment 的机制不同,不存在上述问题。
 
2. Comment Size
NPOI 中要设置 Comment 的大小,暂时只能在创建 Comment 时通过传入的 IClientAnchor 设置其大小。
public interface IDrawing
{
    //...
    IComment CreateCellComment(IClientAnchor anchor);
    //...
}
通过设置 IClientAnchor 的四个属性可以设置 Comment 的大小。
public interface IClientAnchor
{
    //...
    int Col1 { get; set; }
    int Col2 { get; set; }
    int Row1 { get; set; }
    int Row2 { get; set; }
    //...
}
这样设置的 Comment 大小与这四个属性指示的这些单元格的大小相关。如果这些单元格变宽,Comment 的宽度也会相应增加(高度也一样)。无法设置固定大小。
(Microsoft.Office.Interop.Excel 中可以通过 Comment 的 Shape 属性设置固定的大小)
 
分享到:
评论

相关推荐

    .NET Core使用NPOI导出复杂Word-NPOI-Export-Word-master.zip

    首先看了下GItHub中的源码有一个简单Word导出的示例,然后在看了网上有很多关于NPOI导出Word文档的案例,发现一个特点网上的好像都差不多,对于我而言网上的这些案例完全能够实现我的这个功能,但是感觉看了网上这些...

    Npoi生成Excel 97-2003/ (xls)文件

    NPOI 是 POI 项目的 .NET... 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作。

    NPOI.rar_-baijiahao_NPOI word_npoi _npoi帮助文档_npoi教程

    在“NPOI.rar”压缩包中,包含了一个名为“NPOI帮助文档(1.2.3版).chm”的文件,这是一份详细介绍了NPOI 1.2.3版本的使用教程。CHM是Microsoft编写的HTML帮助文件,可以方便地查看和搜索相关知识。 NPOI的核心功能...

    Unity文档操作使用的NPOI库文件

    在Unity中,虽然它是基于.NET Framework的,但通过IL2CPP或者Unity的.NET 4.x兼容性设置,我们可以在Unity项目中使用NPOI。 标题中提到的"Unity文档操作使用的NPOI库文件",意味着我们要在Unity中集成NPOI库,用于...

    NPOI-import-and-export-Excel.rar_C# EXCEL npoi_C# npoi_excel_imp

    在使用NPOI过程中,可能会遇到各种异常,如文件不存在、格式不正确、内存不足等。需要适当地捕获和处理这些异常,确保程序的健壮性。 总结,NPOI是一个强大且易用的C#库,适用于处理Excel文件。无论是在C/S架构的...

    npoi-master-excel操作例程

    What's NPOI This project is the .NET version of POI Java project at http://poi.apache.org/. POI is an open source project which can help you read/write xls, doc, ppt files. It has a wide application. ...

    NPOI-2.4-稳定版.rar

    9. **安全考虑**:NPOI处理的文件可能包含敏感数据,因此在使用时需要注意数据保护和安全编程实践,防止潜在的安全风险。 总的来说,NPOI是一个强大的工具,为.NET开发者提供了便捷的接口来处理Office文件,尤其在...

    使用NPOI操作制作word

    使用NPOI操作制作word NPOI是一个流行的开源库,允许开发人员在.NET平台下生成和操作Office文档。下面我们将详细介绍如何使用NPOI操作生成word文档,包括生成段落、添加文字、添加页眉、插入图片、插入柱形图和表格...

    NPOI使用手册.doc

    NPOI采用Apache 2.0许可证,这使得它在商业和非商业项目中都能自由使用,无需担心源代码开放的问题。这对于那些需要在业务系统开发中集成Excel功能的公司来说,是一个极具吸引力的选择。 ### 1. 了解NPOI 1.1 什么...

    npoi.2.4.1-C#.rar

    3. **性能优化**:NPOI设计时考虑了性能,尤其是在处理大型Excel文件时。它允许流式读写,避免一次性加载整个文件到内存,减少了内存消耗。 4. **数据导出**:在企业级应用中,NPOI常用于数据导出,如将数据库中的...

    NPOI-1.2.4-(2.0and4.0)DLL.rar_NPOI dll_NPOI.dll 2.4_npoi 2.0_npo

    标题提到的"NPOI-1.2.4-(2.0and4.0)DLL.rar"是一个包含不同版本NPOI DLL文件的压缩包,其中".net 4.0"和".net 2.0"分别对应于.NET Framework 4.0和2.0版本的库。 NPOI 2.0和NPOI 4.0的主要区别在于功能增强、性能...

    WinForm使用NPOI-NET.2.0-导入导出+示例.zip

    在这个场景中,"WinForm使用NPOI-NET.2.0-导入导出+示例.zip" 提供了一个解决方案,允许开发者在不安装Microsoft Office的情况下,通过C#语言在WinForm应用中实现Excel文件的导入和导出功能。NPOI是一个开源库,专门...

    NPOI.dll(C#版本)

    在实际使用NPOI.dll时,开发者需要引用这个库,然后通过调用其提供的类和方法来实现所需功能。例如,`HSSFWorkbook`代表一个Excel工作簿,`HSSFSheet`表示工作簿中的工作表,`HSSFRow`和`HSSFCell`则分别对应工作表...

    C#使用NPOI操作合并单元格

    在C#中使用NPOI处理Excel文件时,可以通过`ISheet`对象获取到合并区域的信息。下面的代码片段展示了如何通过`ISheet`对象获取合并区域的数量以及具体的范围: ```csharp var mergedRegions = sheet....

    C#使用NPOI导入Excel的方法详解

    本文实例讲述了C#使用NPOI导入Excel的方法。分享给大家供大家参考,具体如下: NPOI是由国人开发的一个进行excel操作的第三方库。百度百科介绍如下:NPOI 本文主要介绍如何使用NPOI将Excel数据读取。 首先引入程序集...

    NPOI使用手册(基础)

    NPOI支持在Cell中设置公式,例如`SetCellFormula("A1+B1")`。同时,也可以创建带有超链接的单元格,通过`Hyperlink`类实现。 9. **保存文件** 完成操作后,使用Workbook的`Write`方法将内容写入OutputStream,...

    NPOIexcel导入导出

    在使用NPOI进行导入导出时,可能会遇到各种错误,如文件格式不正确、内存不足等。了解并正确处理这些异常是确保程序稳定性的关键。 9. **示例代码** 下面是一个简单的示例,展示如何使用NPOI创建一个新的Excel...

    Labview读写Excel,使用C#封装NPOI

    在IT行业中,处理数据是常见的任务之一,而Excel作为广泛使用的电子表格软件,其读写功能在各种场景下都十分实用。本主题聚焦于在Labview环境下如何更高效地进行Excel操作,通过C#封装NPOI库来实现这一目标。 首先...

    npoi使用示例.rar

    3. **问题(issues)**:这部分可能包含了用户在使用NPOI时遇到的问题和解决方案,对于初学者来说,这是一个宝贵的参考资料,可以从中学习到常见问题的处理方法。 4. **许可证(license)**:NPOI是一个开源项目,...

    C#使用npoi操作office案例

    C#使用npoi操作office案例C#使用npoi操作office案例C#使用npoi操作office案例C#使用npoi操作office案例C#使用npoi操作office案例C#使用npoi操作office案例

Global site tag (gtag.js) - Google Analytics