处理 XML 格式的Excel

今天来处理几份XML文件,都是Excel,命名齐全;

但第三方组件无法读取,出现:ERROR:Invalid file signature

 细看也是一份标准的xml文件,通过XMLDocument能处理,依据需求不同自行修改;

  1 public static class XMLtoDataTable
  2     {
  3         private static ColumnType getDefaultType()
  4         {
  5             return new ColumnType(typeof(String));
  6         }
  7 
  8         struct ColumnType
  9         {
 10             public Type type;
 11             private string name;
 12             public ColumnType(Type type) { this.type = type; this.name = type.ToString().ToLower(); }
 13             public object ParseString(string input)
 14             {
 15                 if (String.IsNullOrEmpty(input))
 16                     return DBNull.Value;
 17                 switch (type.ToString())
 18                 {
 19                     case "system.datetime":
 20                         return DateTime.Parse(input);
 21                     case "system.decimal":
 22                         return decimal.Parse(input);
 23                     case "system.boolean":
 24                         return bool.Parse(input);
 25                     default:
 26                         return input;
 27                 }
 28             }
 29         }
 30 
 31         private static ColumnType getType(XmlNode data)
 32         {
 33             string type = null;
 34             if (data.Attributes["ss:Type"] == null || data.Attributes["ss:Type"].Value == null)
 35                 type = "";
 36             else
 37                 type = data.Attributes["ss:Type"].Value;
 38 
 39             switch (type)
 40             {
 41                 case "DateTime":
 42                     return new ColumnType(typeof(DateTime));
 43                 case "Boolean":
 44                     return new ColumnType(typeof(Boolean));
 45                 case "Number":
 46                     return new ColumnType(typeof(Decimal));
 47                 case "":
 48                     decimal test2;
 49                     if (data == null || String.IsNullOrEmpty(data.InnerText) || decimal.TryParse(data.InnerText, out test2))
 50                     {
 51                         return new ColumnType(typeof(Decimal));
 52                     }
 53                     else
 54                     {
 55                         return new ColumnType(typeof(String));
 56                     }
 57                 default://"String"
 58                     return new ColumnType(typeof(String));
 59             }
 60         }
 61 
 62         public static DataSet ImportExcelXML(string fileName, bool hasHeaders, bool autoDetectColumnType)
 63         {
 64             using (StreamReader sr = new StreamReader(fileName))
 65             {
 66                 using (Stream st = (Stream)sr.BaseStream)
 67                 {
 68                     return ImportExcelXML(st, hasHeaders, autoDetectColumnType);
 69                 }
 70             }
 71         }
 72 
 73         private static DataSet ImportExcelXML(Stream inputFileStream, bool hasHeaders, bool autoDetectColumnType)
 74         {
 75             XmlDocument doc = new XmlDocument();
 76             doc.Load(new XmlTextReader(inputFileStream));
 77             XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
 78 
 79             nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office");
 80             nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
 81             nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");
 82 
 83             DataSet ds = new DataSet();
 84             foreach (XmlNode node in doc.DocumentElement.SelectNodes("//ss:Worksheet", nsmgr))
 85             {
 86                 DataTable dt = new DataTable(node.Attributes["ss:Name"].Value);
 87                 ds.Tables.Add(dt);
 88                 XmlNodeList rows = node.SelectNodes("ss:Table/ss:Row", nsmgr);
 89                 var colcount = node.SelectNodes("ss:Table/ss:Column", nsmgr).Count;
 90                 if (rows.Count > 0)
 91                 {
 92                     //*************************
 93                     //判断列标题并加入Table
 94                     //*************************
 95                     List<ColumnType> columns = new List<ColumnType>();
 96                     int startIndex = 0;
 97                     if (hasHeaders)
 98                     {
 99                         for (; ; )
100                         {
101                             if (rows[startIndex].SelectNodes("ss:Cell/ss:Data", nsmgr).Count < colcount)
102                             {
103                                 startIndex++;
104                                 continue;
105                             }
106                             foreach (XmlNode data in rows[startIndex].SelectNodes("ss:Cell/ss:Data", nsmgr))
107                             {
108                                 columns.Add(new ColumnType(typeof(string)));//default to text
109                                 dt.Columns.Add(data.InnerText, typeof(string));
110                             }
111                             break;
112                         }
113                         startIndex++;
114                     }
115 
116                     //*************************
117                     //如果 Auto-Detecting 更新列 Data-Types 
118                     //*************************
119                     if (autoDetectColumnType && rows.Count > 0)
120                     {
121                         XmlNodeList cells = rows[startIndex].SelectNodes("ss:Cell", nsmgr);
122                         int actualCellIndex = 0;
123                         for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++)
124                         {
125                             XmlNode cell = cells[cellIndex];
126                             if (cell.Attributes["ss:Index"] != null)
127                                 actualCellIndex =int.Parse(cell.Attributes["ss:Index"].Value) - 1;
128 
129                             ColumnType autoDetectType = getType(cell.SelectSingleNode("ss:Data", nsmgr));
130 
131                             if (actualCellIndex >= dt.Columns.Count)
132                             {
133                                 dt.Columns.Add("Column" + cellIndex.ToString(), autoDetectType.type);
134                                 columns.Add(autoDetectType);
135                             }
136                             else
137                             {
138                                 dt.Columns[actualCellIndex].DataType = autoDetectType.type;
139                                 columns[actualCellIndex] = autoDetectType;
140                             }
141 
142                             actualCellIndex++;
143                         }
144                     }
145                     //*************************
146                     //加载数据
147                     //*************************
148                     for (int i = startIndex; i < rows.Count; i++)
149                     {
150                         DataRow row = dt.NewRow();
151                         XmlNodeList cells = rows[i].SelectNodes("ss:Cell", nsmgr);
152                         int actualCellIndex = 0;
153                         for (int cellIndex = 0; cellIndex < cells.Count; cellIndex++)
154                         {
155                             XmlNode cell = cells[cellIndex];
156                             if (cell.Attributes["ss:Index"] != null)
157                                 actualCellIndex = int.Parse(cell.Attributes["ss:Index"].Value) - 1;
158 
159                             XmlNode data = cell.SelectSingleNode("ss:Data", nsmgr);
160 
161                             if (actualCellIndex >= dt.Columns.Count)
162                             {
163                                 for (int ii = dt.Columns.Count; ii < actualCellIndex; ii++)
164                                 {
165                                     dt.Columns.Add("Column" + ii.ToString(), typeof(string)); 
166                                     columns.Add(getDefaultType());
167                                 } 
168                                 ColumnType autoDetectType = getType(cell.SelectSingleNode("ss:Data", nsmgr));
169                                 dt.Columns.Add("Column" + actualCellIndex.ToString(),typeof(string));
170                                 columns.Add(autoDetectType);
171                             }
172                             if (data != null)
173                                 row[actualCellIndex] = data.InnerText;
174 
175                             actualCellIndex++;
176                         }
177 
178                         dt.Rows.Add(row);
179                     }
180                 }
181             }
182             return ds;
183         }
184 
185 
186     }
View Code
原文地址:https://www.cnblogs.com/MR520/p/14649360.html