编程语言
首页 > 编程语言> > c# – 使用OpenXML和SAX模板

c# – 使用OpenXML和SAX模板

作者:互联网

我正在使用Parsing and Reading Large Excel Files with the Open XML SDK中提出的SAX方法从数据表创建一个大型XLSX文件.我正在使用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()和OpenXmlReader.WriteStartElement()的组合从模板表复制到新工作表.

当元素是OpenXmlLeafTextElement时,OpenXmlReader.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();
        }
    }
}

标签:c,excel,openxml,openxml-sdk,sax
来源: https://codeday.me/bug/20190613/1235676.html