[英]Using a template with OpenXML and SAX
我正在從數據表創建一個大型 XLSX 文件,使用在Parsing and Reading Large Excel Files with the Open XML SDK 中提出的 SAX 方法。 我使用 XLSX 文件作為模板。
該帖子中描述的方法可以很好地替換現有工作表中的新工作表,但我想從模板中的工作表復制標題行(字符串值、格式等),而不是僅使用來自與原始代碼一樣的數據表。
我已經嘗試了下面的代碼,但是 XLSX 文件的標題行中沒有文本 - 格式被復制,而不是文本。 我查看了工作表的 XML 文件,對我來說它看起來沒問題(引用了 sharedStrings.xml 文件,它仍然具有字符串的定義)。 來自Open XML SDK 2.0 Productivity Tool的反射代碼顯示了一個稍微奇怪的結果:單元格似乎沒有設置文本值:
cellValue1.Text = "";
即使 XML 說:
<x:c r="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();
}
}
}
線索是生產力工具在生成的工作表上顯示標題單元格的空白值,並且模板中的驗證公式丟失。 這些都是文本,沒有使用OpenXmlReader.Read()
和OpenXmlReader.WriteStartElement()
的組合從模板工作表復制到新工作表。
當元素是OpenXmlLeafTextElement
, OpenXmlReader.GetText()
方法將返回文本 - 這適用於單元格中的文本值和公式。
工作代碼如下所示:
while (openXmlReader.Read())
{
if (openXmlReader.ElementType == typeof(SheetData))
{
if (openXmlReader.IsEndElement)
continue;
// write sheet element
openXmlWriter.WriteStartElement(new SheetData());
// read first row from template and copy into the new sheet
openXmlReader.Read();
do
{
if (openXmlReader.IsStartElement)
{
openXmlWriter.WriteStartElement(openXmlReader);
// this bit is needed to get cell values
if (openXmlReader.ElementType.IsSubclassOf(typeof(OpenXmlLeafTextElement)))
{
openXmlWriter.WriteString(openXmlReader.GetText());
}
}
else if (openXmlReader.IsEndElement)
{
openXmlWriter.WriteEndElement();
}
openXmlReader.Read();
} while (!(openXmlReader.ElementType == typeof(Row) && openXmlReader.IsEndElement));
openXmlWriter.WriteEndElement();
// write data rows
foreach (DataRow dataRow in resultsTable.Rows)
{
// write row element
Row r = new Row();
openXmlWriter.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
openXmlWriter.WriteElement(c);
}
// end row
openXmlWriter.WriteEndElement();
}
// end sheet
openXmlWriter.WriteEndElement();
}
else
{
if (openXmlReader.IsStartElement)
{
openXmlWriter.WriteStartElement(openXmlReader);
// this bit is needed to get formulae and that kind of thing
if (openXmlReader.ElementType.IsSubclassOf(typeof(OpenXmlLeafTextElement)))
{
openXmlWriter.WriteString(openXmlReader.GetText());
}
}
else if (openXmlReader.IsEndElement)
{
openXmlWriter.WriteEndElement();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.