使用C#中的Open XML SDK读取特定列的Excel单元格值

时间:2018-10-04 12:58:18

标签: c# excel openxml-sdk

我将这些数据保存在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)

我已经搜索了一段时间,但找不到如何执行此操作。任何帮助表示赞赏。预先感谢。

1 个答案:

答案 0 :(得分:1)

从下面的方法中,您可以将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;
        }