簡體   English   中英

在 OpenXML 和 SAX 中使用模板

[英]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()的組合從模板工作表復制到新工作表。

當元素是OpenXmlLeafTextElementOpenXmlReader.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM