private void Read(List <T> obj, Worksheet sheet, RangePosition targetRange, int bufferItems = DEFAULT_READ_BUFFER_ITEMS, bool autoSpread = true) { targetRange = sheet.FixRange(targetRange); Type type = typeof(T); T[] items = new T[bufferItems]; List <object>[] bufferLineList = new List <object> [bufferItems]; for (int i = 0; i < bufferLineList.Length; i++) { bufferLineList[i] = new List <object>(256); } #if DEBUG var sw = System.Diagnostics.Stopwatch.StartNew(); #endif int row = targetRange.Row; int totalReadItems = 0; sheet.SuspendDataChangedEvents(); int maxCols = 0; try { bool finished = false; while (!finished) { int readItems = 0; for (; readItems < items.Length; readItems++) { if (totalReadItems >= obj.Count) { finished = true; break; } items[readItems] = obj[totalReadItems]; totalReadItems++; if (!autoSpread && totalReadItems > targetRange.Rows) { finished = true; break; } } if (autoSpread && row + readItems > sheet.RowCount) { int appendRows = bufferItems - (sheet.RowCount % bufferItems); if (appendRows <= 0) { appendRows = bufferItems; } sheet.AppendRows(appendRows); } for (int i = 0; i < readItems; i++) { var item = items[i]; var toBuffer = bufferLineList[i]; toBuffer.Clear(); foreach (var m in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(w => w.CanWrite)) { toBuffer.Add(m.GetValue(item, null)); if (toBuffer.Count >= targetRange.Cols) { break; } } if (maxCols < toBuffer.Count) { maxCols = toBuffer.Count; } if (autoSpread && maxCols <= sheet.ColumnCount) { sheet.SetCols(maxCols + 1); } } sheet.SetRangeData(row, targetRange.Col, readItems, maxCols, bufferLineList); row += readItems; } } finally { sheet.ResumeDataChangedEvents(); } sheet.RaiseRangeDataChangedEvent(new RangePosition(targetRange.Row, targetRange.Col, maxCols, totalReadItems)); #if DEBUG sw.Stop(); System.Diagnostics.Debug.WriteLine("load generic list: " + sw.ElapsedMilliseconds + " ms, rows: " + row); #endif }