C#读取Excel数据动态生成对象并进行序列化
由于工作需要,要把Excel数据(格式如下图)读取出来并动态创建类,并利用数据去实例化,然后在进行序列化存储。
要读取Excels数据就必须了解Excel的存储结构和存储方法,才能进行读取操作,从参考⑨+1中可知,.xlsx是一组.xml文件的集合,可以把.xlsx后缀名改成.zip,然后在打开就可以看到,既然是这样我们就可以从解析xml角度去读取xlsx的数据,可以参考⑨+1的解决办法。
Excel的数据有两个作用:
1)动态创建类
上图要创建类为:
public class DynamicClass { public string id; public string name; public string chapter_x; public unit x; public unit y; }
2)实例化对象
然后Value的每一行都是用来实例化类DynamicClass的对象。
因此,首要任务是对Excel文件进行读写,我google了下,发现读取Excel数据大概有三种方法:
1)采用OleDB读取文件
2)引用com组件:Microsoft.Office.INterop.Excel.dll,读取文件(本文就是采取这种方法的)
3)其他格式读取,如转成CSV或Zip进行读取
当然还有其他利用第三方包的方法。
方法1)读取效率高,在C#使用OleDb读取Excel,生成SQL语句使用的就是这个方法,但是方法1)只能读取单元格的“正文”数据,像批注等不能读取到(没有看到相关api)。
我这里采用的是2)的方法且参考②中代码进行改装的,把读取Excel的数据保存在StringBuilder classSource,objectData中,classSource用来动态创建类的“源代码”,objectData则是把所有对象数据存储起来。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using Excel = Microsoft.Office.Interop.Excel; namespace ReadXlsxData { static class ParseXlsx { public static Excel.Application m_ExcelFile = new Excel.Application(); public static StringBuilder classSource; public static StringBuilder objectData; public static void CloseExcelApplication() { m_ExcelFile.Quit(); m_ExcelFile = null; } public static void ReadExcelFile(string excelFilePath) { classSource = new StringBuilder(); ; objectData = new StringBuilder(); Excel._Workbook m_Workbook; Excel._Worksheet m_Worksheet; object missing = System.Reflection.Missing.Value; Console.WriteLine("excelFilePath:" + excelFilePath); m_ExcelFile.Workbooks.Open(excelFilePath, missing, missing, missing, missing, missing, missing, missing, missing, missing , missing, missing, missing, missing, missing); m_ExcelFile.Visible = false; m_Workbook = m_ExcelFile.Workbooks[1]; m_Worksheet = (Excel.Worksheet)m_Workbook.ActiveSheet; int clomn_Count = m_Worksheet.UsedRange.Columns.Count; int row_Count = m_Worksheet.UsedRange.Rows.Count; classSource.Append("using System;\n"); classSource.Append("[Serializable]\n"); classSource.Append("public class DynamicClass \n"); classSource.Append("{\n"); string propertyName,propertyType; for (int j = 2; j < clomn_Count + 1; j++) { propertyName = ((Excel.Range)m_Worksheet.Cells[3, j]).Text.ToString(); propertyType=((Excel.Range)m_Worksheet.Cells[4, j]).Text.ToString() ; classSource.Append(" private "