2

尝试读取加密的 2007 Excel 文档时,我在使用 OOXML 库时遇到问题。我发送给 DecryptToStream 方法的密码发送回“密码无效”消息,但如果我直接进入 excel,密码可以正常工作。下面是我正在使用的代码。

OleStorage ols = new OleStorage(d.fileLocation);
OfficeCrypto oc = new OfficeCrypto();
Stream test = oc.DecryptToStream(ols, "test123");

我也尝试使用 POI Decryptor 尝试读取加密的 2007 excel,但我也没有运气。下面是代码。

FileStream file = new FileStream(d.fileLocation, FileMode.Open, System.IO.FileAccess.Read);
NPOI.POIFS.FileSystem.POIFSFileSystem nfs;
nfs = new NPOI.POIFS.FileSystem.POIFSFileSystem(file);
Stream excelData;
try
{
    string password = "test123";
    EncryptionInfo info = new EncryptionInfo(nfs);
    Decryptor dc = Decryptor.GetInstance(info);

    if (!dc.VerifyPassword(password))
    {
        throw new NotImplementedException();
    }

    excelData = dc.GetDataStream(nfs);

}
catch (Exception ex)
{
    excelData = (Stream)file;
}

无论我传递什么,VerifyPassword 方法总是返回 true,它仍然不会读取文档。我使用http://poi.apache.org/encryption.html作为参考创建了上述代码。

任何帮助将不胜感激!

4

1 回答 1

3

据我所知,目前的NPOI 1.2.5 版本不支持 Excel2007 文件。幸运的是, NPOI 2.0 alpha 版本 确实支持 Excel2007 文件,但不支持加密的 Excel 文件。

但是,有一个名为OfficeOpenXmlCrypto的项目 支持读取加密的 Excel 文件。该项目基于 NPOI 1.2.1 版和ExcelPackage项目来读取 Excel 2007 文件。

您可以下载OfficeOpenXmlCrypto项目的源代码,将旧的 NPOI 库替换为新的 NPOI 2.0 库并编译项目。

然后,您可以使用XSSFWorkbookOfficeCryptoStream类的组合来读取加密的 Excel 文件的内容:

using (OfficeCryptoStream ocs = OfficeCryptoStream.Open("c:\\temp\\secured.xlsx", "PA$$W0rd"))
{
  NPOI.XSSF.UserModel.XSSFWorkbook w = new NPOI.XSSF.UserModel.XSSFWorkbook(ocs);

  NPOI.xssf.extractor.XSSFExcelExtractor ee = new NPOI.xssf.extractor.XSSFExcelExtractor(w);

  Console.Out.WriteLine(ee.Text);                    
}

作为替代方案,EPPlus 类库 提供了一个名为的类,该类ExcelPackage提供对加密 Excel 文档的支持。此类还有一些属性 ( Workbook) 用于访问 Excel 文档的内容。

这是一个读取加密 Excel 文件的第一个单元格的简单示例:

using (FileStream file = new FileStream("c:\\temp\\secure.xlsx", 
       FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
{
  using (ExcelPackage ep = new ExcelPackage(file, "P@$$W0rd"))
  {
    Console.Out.WriteLine(ep.Workbook.Worksheets[1].Cells["A1"].Value);     
  }
} 

您还可以将OpenXml 2.0 SDK SpreadsheetDocument类与ExcelPackage该类结合使用。

使用以下代码读取第一个单元格的内容(加密的 Excel 文档):

using (FileStream file = new FileStream("c:\\temp\\secure.xlsx", 
       FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
{
  using (ExcelPackage ep = new ExcelPackage(file, "P@$$W0rd"))
  {     
    using (SpreadsheetDocument sd = SpreadsheetDocument.Open(ep.Package))
    {
      WorkbookPart workbookPart = sd.WorkbookPart;
      WorksheetPart worksheetPart = workbookPart.WorksheetParts.Last();
      SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

      var row = sheetData.Elements<Row>().FirstOrDefault();
      var cell = row.Elements<Cell>().FirstOrDefault();

      Console.Out.WriteLine(cell.CellValue.InnerText);
    }
  }
}

如果密码无效,该类的构造函数ExcelPackage会抛出一个。UnauthorizedAccessException

于 2012-09-26T18:25:36.463 回答