c# – 通过HSSF.EventUserModel使用受保护的书籍和工作表读取XLS
结束目标:有效地(一次性)读取一个巨大的(30,000行)受保护的工作表上的所有CellRecords.
问题: 创建输入电子表格(在Excel 2010中): >创建新的空白工作簿. 迄今取得的进展: >在Excel中没有密码的情况下打开XLS文件.因此,您不需要密码才能在POI中打开它. 注意: 码: 我只是在调试器中查看processedEvents. using System; using System.Collections.Generic; using System.IO; using NPOI.HSSF.Record; using NPOI.HSSF.Model; using NPOI.HSSF.UserModel; using NPOI.HSSF.EventUserModel; using NPOI.POIFS; using NPOI.POIFS.FileSystem; namespace NPOI_small { class myListener : IHSSFListener { List<Record> processedRecords; private Stream fs; public myListener(Stream fs) { processedRecords = new List<Record>(); this.fs = fs; HSSFEventFactory factory = new HSSFEventFactory(); HSSFRequest request = new HSSFRequest(); MissingRecordAwareHSSFListener mraListener; FormatTrackingHSSFListener fmtListener; EventWorkbookBuilder.SheetRecordCollectingListener recListener; mraListener = new MissingRecordAwareHSSFListener(this); fmtListener = new FormatTrackingHSSFListener(mraListener); recListener = new EventWorkbookBuilder.SheetRecordCollectingListener(fmtListener); request.AddListenerForAllRecords(recListener); POIFSFileSystem poifs = new POIFSFileSystem(this.fs); factory.ProcessWorkbookEvents(request,poifs); } public void ProcessRecord(Record record) { processedRecords.Add(record); } } class Program { static void Main(string[] args) { Stream fs = File.OpenRead(@"c:usersmedesktopxxBook1-protected.xls"); myListener testListener = new myListener(fs); // Use EventModel //HSSFWorkbook book = new HSSFWorkbook(fs); // Use UserModel Console.Read(); } } } 更新(胡安梅拉多): > processedRecords [5]是一个WriteAccessRecord,带有.name的乱码(可能是加密的)值 例外: NPOI.Util.RecordFormatException was unhandled HResult=-2146233088 Message=Unable to construct record instance Source=NPOI StackTrace: at NPOI.HSSF.Record.RecordFactory.ReflectionConstructorRecordCreator.Create(RecordInputStream in1) at NPOI.HSSF.Record.RecordFactory.CreateSingleRecord(RecordInputStream in1) at NPOI.HSSF.Record.RecordFactory.CreateRecord(RecordInputStream in1) at NPOI.HSSF.EventUserModel.HSSFRecordStream.GetNextRecord() at NPOI.HSSF.EventUserModel.HSSFRecordStream.NextRecord() at NPOI.HSSF.EventUserModel.HSSFEventFactory.GenericProcessEvents(HSSFRequest req,RecordInputStream in1) at NPOI.HSSF.EventUserModel.HSSFEventFactory.ProcessEvents(HSSFRequest req,Stream in1) at NPOI.HSSF.EventUserModel.HSSFEventFactory.ProcessWorkbookEvents(HSSFRequest req,POIFSFileSystem fs) at NPOI_small.myListener..ctor(Stream fs) in c:UsersmeDocumentsVisual Studio 2012ProjectsmyTestNPOI_smallProgram.cs:line 35 at NPOI_small.Program.Main(String[] args) in c:UsersmeDocumentsVisual Studio 2012ProjectsmyTestNPOI_smallProgram.cs:line 80 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: NPOI.Util.RecordFormatException HResult=-2146233088 Message=Expected to find a ContinueRecord in order to read remaining 137 of 144 chars Source=NPOI StackTrace: at NPOI.HSSF.Record.RecordInputStream.ReadStringCommon(Int32 requestedLength,Boolean pIsCompressedEncoding) at NPOI.HSSF.Record.RecordInputStream.ReadUnicodeLEString(Int32 requestedLength) at NPOI.HSSF.Record.FontRecord..ctor(RecordInputStream in1) 解决方法
我认为这是NPOI库代码中的错误.据我所知,他们使用不正确的流类型为HSSFEventFactory:它使用RecordInputStream而不是RecordFactoryInputStream与解密函数,如原始POI库或UserModel(这就是为什么HSSFWorkbook工作)
这段代码也有效,但它不是一个事件逻辑: POIFSFileSystem poifs = new POIFSFileSystem(fs); Entry document = poifs.Root.GetEntry("Workbook"); DocumentInputStream docStream = new DocumentInputStream((DocumentEntry)document); //RecordFactory factory = new RecordFactory(); //List<Record> records = RecordFactory.CreateRecords(docStream); RecordFactoryInputStream recFacStream = new RecordFactoryInputStream(docStream,true); Record currRecord; while ((currRecord = recFacStream.NextRecord()) != null) ProcessRecord(currRecord); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |