很多的软件项目几乎都包含着对文档的操作,前面已经介绍过两款操作文档的组件,现在介绍一款文档操作的组件NPOI。
NPOI可以生成没有安装在您的服务器上的Microsoft Office套件的Excel报表,并且在后台调用Microsoft Excel ActiveX更有效率;从Office文档中提取文本,以帮助您实现全文索引功能(大多数时候,此功能用于创建搜索引擎); 从Office文档提取图像; 生成包含公式的Excel工作表。
一.NPOI组件概述:
NPOI是完全免费使用; 涵盖Excel的大多数功能(单元格样式,数据格式,公式等);支持xls,xlsx,docx;设计为面向接口(看看NPOI.SS命名空间);支持不仅导出而且导入; .Net 2.0甚至为xlsx和docx(虽然我们也支持.NET 4.0); 来自世界各地的成功案例;巨大的基本例子;对隔离存储没有依赖。
以上是NPOI的优点,其他一些优点可以不用太在意,估计很多人对“支持xls,xlsx,docx”这一特点感觉有些惊讶,因为在很多人的印象里面NPOI就是对Excel进行相关的操作,但是在这里突然看到了对docx也可以操作,这一特点可能让很多人感到欣喜,因为NPOI的的确确是一个很不错的组件,用过的人都说好,我也不例外。
NPOI的运行要求:VS2010与.NET 4.0运行时;VS2005或VS2008与.NET 2.0运行时(SP1);vs2003与.NET 1.1;Mono;ASP.NET中的中等信任环境。
二.NPOI核心类和方法解析:
以上是对NPOI的相关背景和使用环境做了一个简单的介绍,接下来我具体的看一下NPOI的一些核心类和方法,由于下载的是DLL文件,还是采用.NET Reflector对DLL文件进行反编译,以此查看源代码。
如果需要具体的了解NPOI可以直接访问:http://npoi.codeplex.com/SourceControl/latest,提供了NPOI的源码和一些demo,由于本溪介绍的重点是NPOI对Excel的操作,所以下面的类和实例主要是对操作Excel的介绍,如果需要对docx的操作,可以具体查看相应的类demo。

1.XSSFWorkbook类CreateSheet():创建表。
public ISheet CreateSheet(string sheetname)
{
if (sheetname == null)
{
throw new ArgumentException("sheetName must not be null");
}
if (this.ContainsSheet(sheetname, this.sheets.Count))
{
throw new ArgumentException("The workbook already contains a sheet of this name");
}
if (sheetname.Length > 0x1f)
{
sheetname = sheetname.Substring(0, 0x1f);
}
WorkbookUtil.ValidateSheetName(sheetname);
CT_Sheet sheet = this.AddSheet(sheetname);
int index = 1;
foreach (XSSFSheet sheet2 in this.sheets)
{
index = (int) Math.Max((long) (sheet2.sheet.sheetId + 1), (long) index);
}
Label_0099:
foreach (XSSFSheet sheet3 in this.sheets)
{
index = (int) Math.Max((long) (sheet3.sheet.sheetId + 1), (long) index);
}
string fileName = XSSFRelation.WORKSHEET.GetFileName(index);
foreach (POIXMLDocumentPart part in base.GetRelations())
{
if ((part.GetPackagePart() != null) && fileName.Equals(part.GetPackagePart().PartName.Name))
{
index++;
goto Label_0099;
}
}
XSSFSheet item = (XSSFSheet) base.CreateRelationship(XSSFRelation.WORKSHEET, XSSFFactory.GetInstance(), index);
item.sheet = sheet;
sheet.id = item.GetPackageRelationship().Id;
sheet.sheetId = (uint) index;
if (this.sheets.Count == 0)
{
item.IsSelected = true;
}
this.sheets.Add(item);
return item;
}
</div>
2.XSSFSheet类Write():将文件流写入到excel。
internal virtual void Write(Stream stream)
{
bool flag = false;
if (this.worksheet.sizeOfColsArray() == 1)
{
CT_Cols colsArray = this.worksheet.GetColsArray(0);
if (colsArray.sizeOfColArray() == 0)
{
flag = true;
this.worksheet.SetColsArray(null);
}
else
{
this.SetColWidthAttribute(colsArray);
}
}
if (this.hyperlinks.Count > 0)
{
if (this.worksheet.hyperlinks == null)
{
this.worksheet.AddNewHyperlinks();
}
CT_Hyperlink[] array = new CT_Hyperlink[this.hyperlinks.Count];
for (int i = 0; i < array.Length; i++)
{
XSSFHyperlink hyperlink = this.hyperlinks[i];
hyperlink.GenerateRelationIfNeeded(base.GetPackagePart());
array[i] = hyperlink.GetCTHyperlink();
}
this.worksheet.hyperlinks.SetHyperlinkArray(array);
}
foreach (XSSFRow row in this._rows.Values)
{
row.OnDocumentWrite();
}
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary[ST_RelationshipId.NamespaceURI] = "r";
new WorksheetDocument(this.worksheet).Save(stream);
if (flag)
{
this.worksheet.AddNewCols();
}
}
</div>
3.XSSFSheet类CreateRow():创建行。
public virtual IRow CreateRow(int rownum)
{
CT_Row cTRow;
XSSFRow row2 = this._rows.ContainsKey(rownum) ? this._rows[rownum] : null;
if (row2 != null)
{
cTRow = row2.GetCTRow();
cTRow.Set(new CT_Row());
}
else if ((this._rows.Count == 0) || (rownum > this.GetLastKey(this._rows.Keys)))
{
cTRow = this.worksheet.sheetData.AddNewRow();
}
else
{
int count = this.HeadMap(this._rows, rownum).Count;
cTRow = this.worksheet.sheetData.InsertNewRow(count);
}
XSSFRow row3 = new XSSFRow(cTRow, this) {
RowNum = rownum
};
this._rows[rownum] = row3;
return row3;
}
</div>
4.XSSFWorkbook类GetSheet:获取表。
public ISheet GetSheet(string name)
{
foreach (XSSFSheet sheet in this.sheets)
{
if (name.Equals(sheet.SheetName, StringComparison.InvariantCultureIgnoreCase))
{
return sheet;
}
}
return null;
}
</div>
5.WorkbookFactory类:
public class PropertySetFactory
{
public static PropertySet Create(DirectoryEntry dir, string name);
public static PropertySet Create(Stream stream);
public static SummaryInformation CreateSummaryInformation();
public static DocumentSummaryInformation CreateDocumentSummaryInformation();
}
</div>
6.DocumentSummaryInformation:
[Serializable]
public class DocumentSummaryInformation : SpecialPropertySet
{
// Fields
public const string DEFAULT_STREAM_NAME = "\x0005DocumentSummaryInformation";
// Methods
public DocumentSummaryInformation(PropertySet ps);
private void EnsureSection2();
public void RemoveByteCount();
public void RemoveCategory();
public void RemoveCompany();
public void RemoveCustomProperties();
public void RemoveDocparts();
public void RemoveHeadingPair();
public void RemoveHiddenCount();
public void RemoveLineCount();
public void RemoveLinksDirty();
public void RemoveManager();
public void RemoveMMClipCount();
public void RemoveNoteCount();
public void RemoveParCount();
public void RemovePresentationFormat();
public void RemoveScale();
public void RemoveSlideCount();
// Properties
public int ByteCount { get; set; }
public string Category { get; set; }
public string Company { get; set; }
public CustomProperties CustomProperties { get; set; }
public byte[] Docparts { get; set; }
public byte[] HeadingPair { get; set; }
public int HiddenCount { get; set; }
public int LineCount { get; set; }
public bool LinksDirty { get; set; }
public string Manager { get; set; }
public int MMClipCount { get; set; }
public int NoteCount { get; set; }
public int ParCount { get; set; }
public string PresentationFormat { get; set; }
public override PropertyIDMap PropertySetIDMap { get; }
public bool Scale { get; set; }
public int SlideCount { get; set; }
}
</div>

