c# - 在 c# 中使用 open xml sdk 读取特定列的 Excel 单元格值
问题描述
我将这些数据保存在 Excel 文件中,并且能够使用 Open XML 读取整个文件并将其存储在 ArrayList 中。
Acme Auto Dealer
ProductID Model Type Color MaxSpeed Manufacturer
10-01 Fortuner SUV Black 200 Toyota
10-02 Innova MPV Red 200 Toyota
10-03 Altis Car White 200 Toyota
10-04 Land Cruiser SUV Red 200 Toyota
10-05 Vios Car Black 200 Toyota
10-06 Avanza MPV White 200 Toyota
10-07 Wigo Car Grey 200 Toyota
10-08 Rush SUV Red 200 Toyota
10-09 Alphard Van Black 200 Toyota
10-10 Hiace Van Black 200 Toyota
10-11 Hilux Truck Red 200 Toyota
10-12 City Car White 200 Honda
10-13 Brio Car Red 200 Honda
10-14 Civic Car Black 200 Honda
10-15 Jazz Car White 200 Honda
10-16 Accord Car Grey 200 Honda
10-17 Mobilio MPV Grey 200 Honda
10-18 CR-V SUV Black 200 Honda
10-19 Odyssey Van Red 200 Honda
10-20 Ranger Truck White 200 Ford
10-21 Expedition SUV Red 200 Ford
10-22 Explorer SUV Black 200 Ford
10-23 Everest SUV White 200 Ford
10-24 Fiesta Car Grey 200 Ford
10-25 Focus Car White 200 Ford
这是代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace OpenXMLSDK
{
public class Program
{
static void Main(string[] args)
{
var fileName = @"C:\XML\Vehicles.xlsx";
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
ArrayList data = new ArrayList();
foreach (Row r in sheetData.Elements<Row>())
{
foreach (Cell c in r.Elements<Cell>())
{
if (c.DataType != null && c.DataType == CellValues.SharedString)
{
var stringId = Convert.ToInt32(c.InnerText);
data.Add(workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(stringId).InnerText);
}
else if (c.InnerText != null || c.InnerText != string.Empty)
{
data.Add(c.InnerText);
}
}
}
Console.ReadKey();
}
}
}
}
现在我想从特定列中提取值并将这些值存储在字典中。Dictionary<string, List<KeyValuePair<string, string>>>
示例输出将如下所示:
10-01 List(Model=Fortuner, Type=SUV, MaxSpeed=200, Manufacturer=Toyota)
10-02 List(Model=Innova, Type=MPV, MaxSpeed=200, Manufacturer=Toyota)
10-03 List(Model=Altis, Type=Car, MaxSpeed=200, Manufacturer=Toyota)
10-04 List(Model=Land Cruiser, Type=SUV, MaxSpeed=200, Manufacturer=Toyota)
10-05 List(Model=Vios, Type=Car, MaxSpeed=200, Manufacturer=Toyota)
10-06 List(Model=Avanza, Type=MPV, MaxSpeed=200, Manufacturer=Toyota)
10-07 List(Model=Wigo, Type=Car, MaxSpeed=200, Manufacturer=Toyota)
10-08 List(Model=Rush, Type=SUV, MaxSpeed=200, Manufacturer=Toyota)
10-09 List(Model=Alphard, Type=Van, MaxSpeed=200, Manufacturer=Toyota)
10-10 List(Model=Hiace, Type=Van, MaxSpeed=200, Manufacturer=Toyota)
10-11 List(Model=Hilux, Type=Truck, MaxSpeed=200, Manufacturer=Toyota)
10-12 List(Model=City, Type=Car, MaxSpeed=200, Manufacturer=Honda)
10-13 List(Model=Brio, Type=Car, MaxSpeed=200, Manufacturer=Honda)
10-14 List(Model=Civic, Type=Car, MaxSpeed=200, Manufacturer=Honda)
10-15 List(Model=Jazz, Type=Car, MaxSpeed=200, Manufacturer=Honda)
10-16 List(Model=Accord, Type=Car, MaxSpeed=200, Manufacturer=Honda)
10-17 List(Model=Mobilio, Type=MPV, MaxSpeed=200, Manufacturer=Honda)
10-18 List(Model=CR-V, Type=SUV, MaxSpeed=200, Manufacturer=Honda)
10-19 List(Model=Odyssey, Type=Van, MaxSpeed=200, Manufacturer=Honda)
10-20 List(Model=Ranger, Type=Truck, MaxSpeed=200, Manufacturer=Ford)
10-21 List(Model=Expedition, Type=SUV, MaxSpeed=200, Manufacturer=Ford)
10-22 List(Model=Explorer, Type= SUV, MaxSpeed=200, Manufacturer=Ford)
10-23 List(Model=Everest, Type= SUV, MaxSpeed=200, Manufacturer=Ford)
10-24 List(Model=Fiesta, Type=Car, MaxSpeed=200, Manufacturer=Ford)
10-25 List(Model=Focus, Type=Car, MaxSpeed=200, Manufacturer=Ford)
我一直在寻找一段时间,但无法找到如何做到这一点。任何帮助表示赞赏。提前致谢。
解决方案
从下面的方法中,您可以将您的 Excel 工作表数据映射到Dictionary<string, List<KeyValuePair<string, string>>>
.
public void MapExcelToDictionary()
{
var fileName = @"C:\XML\Vehicles.xlsx";
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
//Get sheet from excel
var sheets = workbookPart.Workbook.Descendants<Sheet>();
//First sheet from excel
Sheet sheet = sheets.FirstOrDefault();
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var rows = worksheetPart.Worksheet.Descendants<Row>().ToList();
//Get all data rows from sheet
Row headerRow = rows.First();
var headerCells = headerRow.Elements<Cell>();
int totalColumns = headerCells.Count();
List<string> lstHeaders = new List<string>();
foreach (var value in headerCells)
{
var stringId = Convert.ToInt32(value.InnerText);
lstHeaders.Add(workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(stringId).InnerText);
}
// Remove the header row
rows.RemoveAt(0);
//Dictionary to map row data into key value pair
Dictionary<string, List<KeyValuePair<string, string>>> dict = new Dictionary<string, List<KeyValuePair<string, string>>>();
var productID = string.Empty;
//Iterate to all rows
foreach (Row r in rows)
{
List<KeyValuePair<string, string>> keyValuePairs = new List<KeyValuePair<string, string>>();
//Iterate to all cell in current row
foreach (Cell c in r.Elements<Cell>())
{
if (c.DataType != null && c.DataType == CellValues.SharedString)
{
var stringId = Convert.ToInt32(c.InnerText);
string val = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(stringId).InnerText;
//Find cell index and map each cell and add in key value pair
switch (GetColumnIndex(c.CellReference))
{
case 1:
productID = val;
break;
case 2:
keyValuePairs.Add(new KeyValuePair<string, string>("Model", val));
break;
case 3:
keyValuePairs.Add(new KeyValuePair<string, string>("Type", val));
break;
case 4:
keyValuePairs.Add(new KeyValuePair<string, string>("Color", val));
break;
case 5:
keyValuePairs.Add(new KeyValuePair<string, string>("MaSpeed", val));
break;
case 6:
keyValuePairs.Add(new KeyValuePair<string, string>("Manufacturer", val));
break;
}
}
else if (c.InnerText != null || c.InnerText != string.Empty)
{
//Do code here
}
}
//Add productId and its repsective data to dictionary
dict.Add(productID, keyValuePairs);
}
Console.ReadKey();
}
}
下面的方法可以从excel表中的单元格引用中找到列索引。
private static int? GetColumnIndex(string cellReference)
{
if (string.IsNullOrEmpty(cellReference))
{
return null;
}
string columnReference = Regex.Replace(cellReference.ToUpper(), @"[\d]", string.Empty);
int columnNumber = -1;
int mulitplier = 1;
foreach (char c in columnReference.ToCharArray().Reverse())
{
columnNumber += mulitplier * ((int)c - 64);
mulitplier = mulitplier * 26;
}
return columnNumber + 1;
}
推荐阅读
- amazon-web-services - 为什么 NumberOfMessagesDeleted > NumberOfMessagesSent
- html - 使整个 html 按钮可点击
- github - 除非 PR 有“Ready For Merge”标签,否则不要启用绿色合并按钮
- sql - 更新 JSON 字符串中的值
- c# - ASP .NET Cookie 过期发布方法 + Cookie 过期
- sql-server - 在实体框架工作核心 3.1 中使用存储过程插入数据
- python - 尝试移动数据框中列出的文件时出现 FileNotFoundError
- c - 编写迭代函数来计算数学序列
- hive - 我们可以在单个查询中创建多个分区和存储桶,您能提供语法吗?
- python - Python多处理管理器修剪一些方法