2011-10-04 31 views
4

我使用在Parsing and Reading Large Excel Files with the Open XML SDK中提出的SAX方法從數據表中創建大型XLSX文件。我正在使用XLSX文件作爲模板。在OpenXML和SAX中使用模板

在這篇文章中描述的方法可以很好地替代現有的新工作表,但我想從工作表中複製標題行(字符串值,格式等),而不是僅僅使用數據表中的標題行與原始代碼一樣。

我試過了下面的代碼,但是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(); 
     } 
    } 
} 

回答

7

線索是,生產力工具被顯示空白值所生成的片材上的標題單元,並且還使來自模板的驗證公式缺失。這些都是文字,並未使用OpenXmlReader.Read()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(); 
     } 
    } 
}