[英]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.