在OpenXML和SAX中使用模板

我从数据表创build一个大型的XLSX文件,使用parsing和读取大型Excel文件和Open XML SDK中提出的SAX方法。 我正在使用XLSX文件作为模板。

在这篇文章中描述的方法工作正常,用一个新的工作表replace为一个现有的工作表,但我想复制模板(string值,格式等),工作表中的标题行,而不是使用标题行从数据表作为原始代码。

我已经尝试了下面的代码,但是XLSX文件最终在标题行中没有文本 – 格式被复制,而不是文本。 我查看了表单的XML文件,对我来说看起来还行(引用sharedStrings.xml文件,它仍然有string的定义)。 来自Open XML SDK 2.0生产力工具的reflection代码显示了一个稍微奇怪的结果:单元格似乎没有设置文本值:

cellValue1.Text = ""; 

即使XML说:

 <x:cr="A1" s="4" t="s"> 

下面是OpenXmlReader使用的主要代码:

 while (reader.Read()) { if (reader.ElementType == typeof(SheetData)) { if (reader.IsEndElement) continue; // Write sheet element writer.WriteStartElement(new SheetData()); // copy header row from template reader.Read(); do { if (reader.IsStartElement) { writer.WriteStartElement(reader); } else if (reader.IsEndElement) { writer.WriteEndElement(); } reader.Read(); } while (!(reader.ElementType == typeof(Row) && reader.IsEndElement)); writer.WriteEndElement(); // Write data rows foreach (DataRow dataRow in resultsTable.Rows) { // Write row element Row r = new Row(); writer.WriteStartElement(r); foreach (DataColumn dataCol in resultsTable.Columns) { Cell c = new Cell(); c.DataType = CellValues.String; CellValue v = new CellValue(dataRow[dataCol].ToString()); c.Append(v); // Write cell element writer.WriteElement(c); } // End row writer.WriteEndElement(); } // End sheet writer.WriteEndElement(); } else { if (reader.IsStartElement) { writer.WriteStartElement(reader); } else if (reader.IsEndElement) { writer.WriteEndElement(); } } } 

线索是生产力工具显示在生成的工作表上的标题单元格的空白值,并且还缺less来自模板的validation公式。 这些都是文本,而不是从模板表复制到使用OpenXmlReader.Read()OpenXmlReader.WriteStartElement()的组合的新工作表。

当元素是OpenXmlLeafTextElementOpenXmlReader.GetText()方法将返回文本 – 这适用于单元格和公式中的文本值。

工作代码如下所示:

 while (reader.Read()) { if (reader.ElementType == typeof(SheetData)) { if (reader.IsEndElement) continue; // Write sheet element writer.WriteStartElement(new SheetData()); // read first row from template and copy into the new sheet reader.Read(); do { if (reader.IsStartElement) { writer.WriteStartElement(reader); // this bit is needed to get cell values if (reader.ElementType.IsSubclassOf(typeof(OpenXmlLeafTextElement))) { writer.WriteString(reader.GetText()); } } else if (reader.IsEndElement) { writer.WriteEndElement(); } reader.Read(); } while (!(reader.ElementType == typeof(Row) && reader.IsEndElement)); writer.WriteEndElement(); // Write data rows foreach (DataRow dataRow in resultsTable.Rows) { // Write row element Row r = new Row(); writer.WriteStartElement(r); foreach (DataColumn dataCol in resultsTable.Columns) { Cell c = new Cell(); c.DataType = CellValues.String; CellValue v = new CellValue(dataRow[dataCol].ToString()); c.Append(v); // Write cell element writer.WriteElement(c); } // End row writer.WriteEndElement(); } // End sheet writer.WriteEndElement(); } else { if (reader.IsStartElement) { writer.WriteStartElement(reader); // this bit is needed to get formulae and that kind of thing if (reader.ElementType.IsSubclassOf(typeof(OpenXmlLeafTextElement))) { writer.WriteString(reader.GetText()); } } else if (reader.IsEndElement) { writer.WriteEndElement(); } } }