use*_*858 27 .net c# excel office-interop
我试图将Excel文件读入Data.DataTable列表,虽然使用我当前的方法可能需要很长时间.我特意按工作表逐个单元地去工作表,它往往需要很长时间.有更快的方法吗?这是我的代码:
List<DataTable> List = new List<DataTable>();
// Counting sheets
for (int count = 1; count < WB.Worksheets.Count; ++count)
{
// Create a new DataTable for every Worksheet
DATA.DataTable DT = new DataTable();
WS = (EXCEL.Worksheet)WB.Worksheets.get_Item(count);
textBox1.Text = count.ToString();
// Get range of the worksheet
Range = WS.UsedRange;
// Create new Column in DataTable
for (cCnt = 1; cCnt <= Range.Columns.Count; cCnt++)
{
textBox3.Text = cCnt.ToString();
Column = new DataColumn();
Column.DataType = System.Type.GetType("System.String");
Column.ColumnName = cCnt.ToString();
DT.Columns.Add(Column);
// Create row for Data Table
for (rCnt = 0; rCnt <= Range.Rows.Count; rCnt++)
{
textBox2.Text = rCnt.ToString();
try
{
cellVal = (string)(Range.Cells[rCnt, cCnt] as EXCEL.Range).Value2;
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
{
ConvertVal = (double)(Range.Cells[rCnt, cCnt] as EXCEL.Range).Value2;
cellVal = ConvertVal.ToString();
}
// Add to the DataTable
if (cCnt == 1)
{
Row = DT.NewRow();
Row[cCnt.ToString()] = cellVal;
DT.Rows.Add(Row);
}
else
{
Row = DT.Rows[rCnt];
Row[cCnt.ToString()] = cellVal;
}
}
}
// Add DT to the list. Then go to the next sheet in the Excel Workbook
List.Add(DT);
}
Run Code Online (Sandbox Code Playgroud)
D S*_*ley 17
Caling .Value2是一项昂贵的操作,因为它是一个COM-interop调用.我会将整个范围读入一个数组,然后遍历数组:
object[,] data = Range.Value2;
// Create new Column in DataTable
for (int cCnt = 1; cCnt <= Range.Columns.Count; cCnt++)
{
textBox3.Text = cCnt.ToString();
var Column = new DataColumn();
Column.DataType = System.Type.GetType("System.String");
Column.ColumnName = cCnt.ToString();
DT.Columns.Add(Column);
// Create row for Data Table
for (int rCnt = 1; rCnt <= Range.Rows.Count; rCnt++)
{
textBox2.Text = rCnt.ToString();
string CellVal = String.Empty;
try
{
cellVal = (string)(data[rCnt, cCnt]);
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
{
ConvertVal = (double)(data[rCnt, cCnt]);
cellVal = ConvertVal.ToString();
}
DataRow Row;
// Add to the DataTable
if (cCnt == 1)
{
Row = DT.NewRow();
Row[cCnt.ToString()] = cellVal;
DT.Rows.Add(Row);
}
else
{
Row = DT.Rows[rCnt + 1];
Row[cCnt.ToString()] = cellVal;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果其他人正在使用EPPlus。这个实现很幼稚,但是有一些评论引起了人们的注意。如果要GetWorkbookAsDataSet()在顶部再增加一种方法,它将满足OP的要求。
/// <summary>
/// Assumption: Worksheet is in table format with no weird padding or blank column headers.
///
/// Assertion: Duplicate column names will be aliased by appending a sequence number (eg. Column, Column1, Column2)
/// </summary>
/// <param name="worksheet"></param>
/// <returns></returns>
public static DataTable GetWorksheetAsDataTable(ExcelWorksheet worksheet)
{
var dt = new DataTable(worksheet.Name);
dt.Columns.AddRange(GetDataColumns(worksheet).ToArray());
var headerOffset = 1; //have to skip header row
var width = dt.Columns.Count;
var depth = GetTableDepth(worksheet, headerOffset);
for (var i = 1; i <= depth; i++)
{
var row = dt.NewRow();
for (var j = 1; j <= width; j++)
{
var currentValue = worksheet.Cells[i + headerOffset, j].Value;
//have to decrement b/c excel is 1 based and datatable is 0 based.
row[j - 1] = currentValue == null ? null : currentValue.ToString();
}
dt.Rows.Add(row);
}
return dt;
}
/// <summary>
/// Assumption: There are no null or empty cells in the first column
/// </summary>
/// <param name="worksheet"></param>
/// <returns></returns>
private static int GetTableDepth(ExcelWorksheet worksheet, int headerOffset)
{
var i = 1;
var j = 1;
var cellValue = worksheet.Cells[i + headerOffset, j].Value;
while (cellValue != null)
{
i++;
cellValue = worksheet.Cells[i + headerOffset, j].Value;
}
return i - 1; //subtract one because we're going from rownumber (1 based) to depth (0 based)
}
private static IEnumerable<DataColumn> GetDataColumns(ExcelWorksheet worksheet)
{
return GatherColumnNames(worksheet).Select(x => new DataColumn(x));
}
private static IEnumerable<string> GatherColumnNames(ExcelWorksheet worksheet)
{
var columns = new List<string>();
var i = 1;
var j = 1;
var columnName = worksheet.Cells[i, j].Value;
while (columnName != null)
{
columns.Add(GetUniqueColumnName(columns, columnName.ToString()));
j++;
columnName = worksheet.Cells[i, j].Value;
}
return columns;
}
private static string GetUniqueColumnName(IEnumerable<string> columnNames, string columnName)
{
var colName = columnName;
var i = 1;
while (columnNames.Contains(colName))
{
colName = columnName + i.ToString();
i++;
}
return colName;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
128873 次 |
| 最近记录: |