我正在尝试使用Filehelpers ExcelNPOIStorage从Excel工作表中提取数据。因此我创建了一个类:
public static class UalExcelReader
{
public static UalShipmentRecord[] ReadInput(String pathToFile)
{
var provider = new ExcelNPOIStorage(typeof (UalShipmentRecord))
{
StartRow = 2,
StartColumn = 1,
FileName = pathToFile
};
var res = (UalShipmentRecord[]) provider.ExtractRecords();
return res;
}
}
当然还有模型类:
[DelimitedRecord("|")]
public class UalShipmentRecord
{
public string contentofcol1;
public string contentofcol2;
...
}
但是我收到一个名为ExtractRecords()的IndexOutOfRangeException:
System.IndexOutOfRangeException was unhandled
HResult=-2146233080
Message=Index was outside the bounds of the array.
Source=FileHelpers
StackTrace:
at FileHelpers.RecordOperations.ValuesToRecord(Object[] values)
at FileHelpers.DataLink.DataStorage.ValuesToRecord(Object[] values)
at FileHelpers.ExcelNPOIStorage.ExcelNPOIStorage.ExtractRecords()
at Test.Controller.UalExcelReader.ReadInput(String pathToFile) in c:\TEMP\test\Test\Test\Test\Controller\UalExcelReader.cs:line 17
at Test.App.OnStartup(StartupEventArgs eventArgs) in c:\TEMP\test\Test\Test\Test\App.xaml.cs:line 23
at System.Windows.Application.<.ctor>b__1(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at Test.App.Main() in c:\TEMP\test\Test\Test\Test\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
我正确使用它吗?有一个我可以看的例子吗?
答案 0 :(得分:1)
1)当您的Excel工作表中有空白单元格时,可能会发生此错误。这似乎是ExcelNPOIStorage
检索给定行的值的方式中的潜在问题。
NPOI正在使用NPOI.CellWalk
来遍历每一行中的单元格,这似乎会跳过空白单元格。因此,Values
数组比空白单元格的数量短。
看起来需要采用不同的方法,如下所述:http://poi.apache.org/spreadsheet/quick-guide.html#Iterator
2)当不存在时可能导致空白单元格的内容具有不正确的StartRow
和StartColumn
值。
与StartRow
和StartColumn
的智能感知评论相反,对于ExcelNPOIStorage
,他们是基于0的(而在ExcelStorage
中他们是从1开始的)
来源:https://github.com/MarcosMeli/FileHelpers/blob/master/FileHelpers.ExcelNPOIStorage/Test/Program.cs
鉴于我遇到的问题,我会在上面的评论中使用旧的ExcelStorage
类,它更可靠,但缺点是它依赖于Excel Interop。
答案 1 :(得分:0)
默认情况下,在HSSFWorkbook和XSSFWorkbook类中,NPOI库中的MissingCellPolicy设置为MissingCellPolicy.RETURN_NULL_AND_BLANK。
在相关工作簿实例上将值更改为MissingCellPolicy.CREATE_NULL_AS_BLANK可解决此问题。
FileHelpers.ExcelNPOIStorage
ExcelNPOIStorage.cs(OpenWorkbook方法)
修复第101行
private void OpenWorkbook(string filename)
{
FileInfo info = new FileInfo(filename);
if (info.Exists == false)
throw new FileNotFoundException(string.Concat("Excel File '", filename, "' not found."), filename);
using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
var extension = Path.GetExtension(filename);
if (extension.ToLowerInvariant() == ".xlsx" || extension.ToLowerInvariant() == ".xlsm")
{
mWorkbook = new XSSFWorkbook(file);
}
else
mWorkbook = new HSSFWorkbook(file);
// Next line fix
Line 101 - mWorkbook.MissingCellPolicy = MissingCellPolicy.CREATE_NULL_AS_BLANK;
// Previous line fix
if (String.IsNullOrEmpty(SheetName))
mSheet = mWorkbook.GetSheetAt(mWorkbook.ActiveSheetIndex);
else {
try {
mSheet = mWorkbook.GetSheet(SheetName);
if (mSheet == null) {
throw new ExcelBadUsageException(string.Concat("The sheet '",
SheetName,
"' was not found in the workbook."));
}
var sheetIndex = mWorkbook.GetSheetIndex(mSheet);
mWorkbook.SetActiveSheet(sheetIndex);
}
catch {
throw new ExcelBadUsageException(string.Concat("The sheet '",
SheetName,
"' was not found in the workbook."));
}
}
}
}
在github repo上修复的url下面
答案 2 :(得分:0)
我认为空单元格是一个问题。在我的文件中,我只是在文件中绕数据边缘,这对我有所帮助。尝试用鼠标标记数据并打开字段周围的边缘。