简体   繁体   English

如何在C#中将Excel文件数据导入数据表

[英]How to Import excel file data to data table in c#

I am moving data from excel file to datatable, where 10th row is column values .So i used following code by using EPPLUS library(OfficeOpenXml).When i moved to datatable the Columns are Item,Description,Accountnumber,Tender,Levelnumbers .I said these all are 10th row of the excel file, hence due to merging of top level columns it is coming in a sequence like Item,Column1,Column2,Description,Column3,Column4,Column5,Tender,Column6,Levelnumbers .I need a logic like first i need to skip null rows(no data) for column Levelnumbers then Description column name should be moved to Column4 and current column of Description should be named like 'Edata', so the column sequence should be like Item,Column1,Column2,Edata,Column3,Description,Column5,Tender,Column6,Levelnumbers 我将数据从excel文件移动到数据表,其中第10行是列值。所以我通过使用EPPLUS库(OfficeOpenXml)使用了以下代码。当我移到数据表时,列是Item,Description,Accountnumber,Tender,Levelnumbers 。我说这些都是excel文件的第10行,因此由于合并了顶层列,因此出现的顺序类似于Item,Column1,Column2,Description,Column3,Column4,Column5,Tender,Column6,Levelnumbers 。我需要像这样的逻辑首先,我需要跳过列Levelnumbers空行(无数据),然后将Description列名称移至Column4,并将Description的当前列命名为“ Edata”,因此列序列应类似于Item,Column1,Column2,Edata,Column3,Description,Column5,Tender,Column6,Levelnumbers

So altogether by using following code i got values in data table like 因此,通过使用以下代码,我总共在数据表中得到了值

Item,Column1,Column2,Description,Column3,Column4,Column5,Tender,Column6,Levelnumbers
1,null,null,Efax,null,Edescription1,null,Tfirst,null,123353
2,null,null,Zfax,null,Zdescription1,null,Tsecond,null,null
3,null,null,Xfax,null,Xdescription1,null,Tthird,null,456546

But it should come as like(skipped values which has Levelnumbers blank ),how to achieve it? 但是它应该像(Levellevels为空白的跳过值)一样,如何实现呢?

Item,Column1,Column2,Edata,Column3,Description,Column5,Tender,Column6,Levelnumbers
1,null,null,Efax,null,Edescription1,null,Tfirst,null,123353
3,null,null,Xfax,null,Xdescription1,null,Tthird,null,456546

code used is 使用的代码是

public static DataTable getDataTableFromExcel(string path)
        {
            using (var pck = new OfficeOpenXml.ExcelPackage())
            {
                DataTable tbl = new DataTable();
                try
                {
                    using (var stream = File.OpenRead(path))
                    {
                        pck.Load(stream);
                    }
                    var ws = pck.Workbook.Worksheets.First();
                    bool hasHeader = true; // adjust it accordingly( i've mentioned that this is a simple approach)
                    string ErrorMessage = string.Empty;
                    foreach (var firstRowCell in ws.Cells[10, 1, 17, ws.Dimension.End.Column])
                    {
                        tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
                    }
                    var startRow = hasHeader ? 11 : 1;
                    for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
                    {
                        var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
                        var row = tbl.NewRow();
                        foreach (var cell in wsRow)
                        {
                            row[cell.Start.Column - 1] = cell.Text;
                        }
                        tbl.Rows.Add(row);
                    }
                }
                catch (Exception exp)
                {

                }
                return tbl;
            }
        }

If I understand what you are asking (let me know if not) you just want to be able to filter out rows missing a value in the last column? 如果我了解您的要求(如果没有,请告诉我),您只是想过滤掉最后一列中缺少值的行? Best to do an explicit cell reference call rather then trying something like wsRow.Last() because the wsRow range will only return cells that have values in it so the Last() will never return a reference to the last column cell since it would be null. 最好执行一个显式的单元格引用调用,而不要尝试像wsRow.Last()因为wsRow范围只会返回其中包含值的单元格,因此Last()绝不会返回对最后一个列单元格的引用,因为空值。

As for replacing column names, all you need is an if statement when populating the column list. 至于替换列名,在填充列列表时,您只需要一个if语句。

This should do it: 应该这样做:

//foreach (var firstRowCell in ws.Cells[10, 1, 17, ws.Dimension.End.Column])  -- ASSUME YOU MEANT ONLY THE 10TH ROW?
foreach (var firstRowCell in ws.Cells[10, 1, 10, ws.Dimension.End.Column])
{
    if (!hasHeader)
        tbl.Columns.Add(string.Format("Column {0}", firstRowCell.Start.Column));
    else if(firstRowCell.Text == "Description")
        tbl.Columns.Add("Edata");
    else if (firstRowCell.Text == "Column4")
        tbl.Columns.Add("Description");
    else
        tbl.Columns.Add(firstRowCell.Text);
}

var startRow = hasHeader ? 11 : 1;
for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
    //Skip row if last column is null
    if (ws.Cells[rowNum, ws.Dimension.End.Column].Value == null)
        continue;

    var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
    var row = tbl.NewRow();
    foreach (var cell in wsRow)
    {
        row[cell.Start.Column - 1] = cell.Text;
    }
    tbl.Rows.Add(row);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM