简体   繁体   English

OpenXML - 不从一行中读取空白单元格 C#

[英]OpenXML - Not reading a blank Cell from a row C#

I have an.xlsx file with 3 columns SrNumber,Name,Active in A,B and C columns respectively.我有一个 .xlsx 文件,其中 3 列 SrNumber、Name、Active 分别在 A、B 和 C 列中。

I am reading the content of this file in a DataTable using the source code given in the answer of following question我正在使用以下问题的答案中给出的源代码在 DataTable 中读取此文件的内容

From Excel to DataTable in C# with Open XML 从 Excel 到 C# 中的数据表,打开 XML

I have also did the modificaitons suggested by Sourabh我也做了 Sourabh 建议的修改

It works fine when my content is as follows当我的内容如下时它工作正常

    A           B       C
1   SrNumber    Name    Active
2   1           test1   Yes
3   2           test2   Yes
4   3           test3   Yes
5   4           test4   Yes

Now when I am trying to add a row at 6th position I am entering the data only in B6 and C6 cells.现在,当我尝试在第 6 个 position 中添加一行时,我只在 B6 和 C6 单元格中输入数据。 I have not touched A6 Cell.我没有碰过A6 Cell。

After running that code I am getting my DataTable filled as follows运行该代码后,我的 DataTable 填充如下

在此处输入图像描述

You can see that value entered in B6 coming in first column and value entered in C6 coming in second column.您可以看到在 B6 中输入的值在第一列,在 C6 中输入的值在第二列。 Also row.Descendants<Cell>() returning only 2 cells for the newly entered row.同样row.Descendants<Cell>()只为新输入的行返回 2 个单元格。

Please let me know if any modifications to be done in the source code.如果要对源代码进行任何修改,请告诉我。

//Read the first Sheet from Excel file.
            IXLWorksheet workSheet = workBook.Worksheet(1);

            //Create a new DataTable.
            DataTable dt = new DataTable();

            //Loop through the Worksheet rows.
            bool firstRow = true;
            foreach (IXLRow row in workSheet.Rows())
            {
                //Use the first row to add columns to DataTable.
                if (firstRow)
                {
                    foreach (IXLCell cell in row.Cells())
                    {
                        dt.Columns.Add(cell.Value.ToString());
                    }
                    firstRow = false;
                }
                else
                {
                    //Add rows to DataTable.
                    dt.Rows.Add();
                    int i = 0;
                    //for (IXLCell cell in row.Cells())
                    for (int j=1;j<= dt.Columns.Count;j++)
                    {
                        if (string.IsNullOrEmpty(row.Cell(j).Value.ToString()))
                            dt.Rows[dt.Rows.Count - 1][i] = "";
                        else
                            dt.Rows[dt.Rows.Count - 1][i] = row.Cell(j).Value.ToString();
                        i++;
                    }
                }
            }

Below code should do the trick for you.下面的代码应该为您解决问题。 CellReferenceToIndex is of real importance which does the calculation of actual cell index when we encounter empty cells: CellReferenceToIndex非常重要,当我们遇到空单元格时,它会计算实际的单元格索引:

using System;
using System.Data;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

public static DataTable ReadAsDataTable(string fileName)
{
    DataTable dataTable = new DataTable();
    using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(fileName, false))
    {
        WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
        IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
        Worksheet workSheet = worksheetPart.Worksheet;
        SheetData sheetData = workSheet.GetFirstChild<SheetData>();
        IEnumerable<Row> rows = sheetData.Descendants<Row>();

        foreach (Cell cell in rows.ElementAt(0))
        {
            dataTable.Columns.Add(GetCellValue(spreadSheetDocument, cell));
        }

        foreach (Row row in rows)
        {
            DataRow dataRow = dataTable.NewRow();
            for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
            {
                 Cell cell = row.Descendants<Cell>().ElementAt(i);
                 int actualCellIndex = CellReferenceToIndex(cell);
                 dataRow[actualCellIndex] = GetCellValue(spreadSheetDocument, cell);
            }

            dataTable.Rows.Add(dataRow);
        }

    }
    dataTable.Rows.RemoveAt(0);

    return dataTable;
}

private static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
    SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
    string value = cell.CellValue.InnerXml;

    if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
    {
        return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
    }
    else
    {
        return value;
    }
}

private static int CellReferenceToIndex(Cell cell)
{
    int index = 0;
    string reference = cell.CellReference.ToString().ToUpper();
    foreach (char ch in reference)
    {
        if (Char.IsLetter(ch))
        {
            int value = (int)ch - (int)'A';
            index = (index == 0) ? value : ((index + 1) * 26) + value;
        }
        else
            return index;
    }
    return index;
}

For those who are still unable to do this, simply use CloseXML.Excel with the code below:对于那些仍然无法做到这一点的人,只需使用 CloseXML.Excel 和以下代码:

    public DataTable ImportTable(DataTable dt, string FileName)
    {
        //Open excel file
        Statics.currentProgressValue = 0;
        Statics.maxProgressValue = 100;
        try
        {
            bool fileExist = File.Exists(FileName);
            if (fileExist)
            {
                using (XLWorkbook workBook = new XLWorkbook(FileName))
                {
                    IXLWorksheet workSheet = workBook.Worksheet(1);

                    var rowCount = workSheet.RangeUsed().RowCount();
                    if (rowCount > 0)
                    {
                        //return dt;
                        var colCount = workSheet.Row(1).CellsUsed().Count();
                        if (dt.Columns.Count < colCount)
                            throw new Exception($"Expects at least {dt.Columns.Count} columns.");

                        //Loop through the Worksheet rows.
                        Statics.maxProgressValue = rowCount;
                        for (int i = 1; i < rowCount; i++)
                        {
                            Statics.currentProgressValue += 1;
                            dt.Rows.Add();
                            for (int j = 2; j < dt.Columns.Count; j++)
                            {
                                var cell = (workSheet.Rows().ElementAt(i).Cell(j));
                                if (!string.IsNullOrEmpty(cell.Value.ToString()))
                                    dt.Rows[i - 1][j] = cell.Value.ToString().Trim();
                                else
                                    dt.Rows[i - 1][j] = "";
                            }
                            if (Statics.cancelProgress == true)
                                break;
                        }
                    }

                    return dt;
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error exporting data." +
                Environment.NewLine + ex.Message);
        }
        return dt;
    }

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

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