2014-05-08 25 views
0

我正在使用通过数据集传递的XML Excel生成一个Excel报表。stringwriter.tostring outofmemoryexception仅在vb.net中显示

Private Function getWorksheets(source As DataSet) As String 
      Dim dc As DataColumn 
      Dim sw As StringWriter = New StringWriter() 
      Dim sww As StringWriter = New StringWriter() 
      Dim sheetCount As Integer = 0 


      If (source Is Nothing Or source.Tables.Count = 0) Then 
       sw.Write("<Worksheet ss:Name=""Sheet1"">" + "<Table>" + System.Environment.NewLine + System.Environment.NewLine + "<Row><Cell><Data ss:Type=""String""></Data></Cell></Row>" + System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
       Return sw.ToString() 
      End If 


      For Each dt As DataTable In source.Tables 

       If (dt.Rows.Count = 0) Then 

        sw.Write("<Worksheet ss:Name=""" + replaceXmlChar(dt.TableName) + """>" + System.Environment.NewLine + System.Environment.NewLine + "<Table>" + System.Environment.NewLine + System.Environment.NewLine + "<Row><Cell ss:StyleID=""s62""><Data ss:Type=""String""></Data></Cell></Row>" + System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 

       Else 
        'write each row data 

        For i As Integer = 0 To dt.Rows.Count - 1 

         If ((i Mod rowLimit) = 0) Then 

          'add close tags for previous sheet of the same data table 
          If ((i/rowLimit) > sheetCount) Then 

           sw.Write(System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
           sheetCount = (i/rowLimit) 
          End If 
          'sw.Write((System.Environment.NewLine + System.Environment.NewLine + "<Worksheet ss:Name=" + replaceXmlChar(dt.TableName)) + ((((i/rowLimit) = 0) ? """ : "_" + Convert.ToString(i/rowLimit))) + "\">" + System.Environment.NewLine + System.Environment.NewLine + "<Table>"); 

          sw.Write((System.Environment.NewLine & System.Environment.NewLine & "<Worksheet ss:Name=""" & replaceXmlChar(dt.TableName)) & ((If(((i/rowLimit) = 0), "", "_" & Convert.ToString(i/rowLimit)))) & """>" & System.Environment.NewLine & System.Environment.NewLine & "<Table>") 


          'write column name row 
          sw.Write(System.Environment.NewLine + System.Environment.NewLine + "<Row>") 

          For Each dc In dt.Columns 

           sw.Write(String.Format("<Cell ss:StyleID=""s62""><Data ss:Type=""String"">{0}</Data></Cell>", replaceXmlChar(dc.ColumnName))) 
          Next 
          sw.Write("</Row>") 
         End If 

         sw.Write(System.Environment.NewLine + System.Environment.NewLine + "<Row>") 
         For Each dc In dt.Columns 
          sw.Write(getCell(dc.DataType, dt.Rows(i)(dc.ColumnName))) 
         Next 
         sw.Write("</Row>") 

        Next 
        sw.Write(System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
       End If 
      Next 

      Return String.Format(sw.ToString()) 
End Function 

它在数据集计数20000或更少时正常工作。

当数据集包含超过23000条记录时。

它正确调试,最后这个函数返回的字符串声明,抛出一个错误

System.OutofMemory例外。在c#中也使用了相同的一组编码概念。但它不会返回错误并正常工作。可以任何一个。请找出错误或告诉我正确的方法。

回答

0

最后我以简单的方式解决了我的问题。

我希望这个答案能帮到你。

我使用Stringwriter从数据集写入数据。当我的数据集包含超过20000条记录时,它将引发错误为“System.outofmeory异常”。 由于Stringwriter将您的数据保存在虚拟内存(RAM)中。

所以,我用Streamwriter而不是Stringwriter。

第一步:

我最初创建了带有头部的XML excel。

Dim excelTemp As String = getWorkbookTemplate() 
Dim fs As IO.FileStream 
Dim sw As IO.StreamWriter 
fs = New IO.FileStream(filename, IO.FileMode.Create, IO.FileAccess.Write) 
sw = New IO.StreamWriter(fs) 
sw.Write(excelTemp) -- Here some header for excel files. 
sw.Flush() 
sw.Close() 
fs.Close() -- file closed 
getWorksheets(dsInput,filename) -- calling getworksheet method with dataset and filename 
fs.Close() 

第2步:

Private Sub getWorksheets(source As DataSet,fname As String) 
     Dim dc As DataColumn 
     Dim dr As DataRow 
     Dim sw As StreamWriter = File.AppendText(fname) -- Here my closed file again re-open and write to file directly using streamwriter Appendtext 
     Dim sheetCount As Integer = 0 

    If (source Is Nothing Or source.Tables.Count = 0) Then 
     sw.Write("<Worksheet ss:Name=""Sheet1"">" + "<Table>" + System.Environment.NewLine + System.Environment.NewLine + "<Row><Cell><Data ss:Type=""String""></Data></Cell></Row>" + System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
    End If 

    For Each dt As DataTable In source.Tables 
     If (dt.Rows.Count = 0) Then 
      sw.Write("<Worksheet ss:Name=""" + replaceXmlChar(dt.TableName) + """>" + System.Environment.NewLine + System.Environment.NewLine + "<Table>" + System.Environment.NewLine + System.Environment.NewLine + "<Row><Cell ss:StyleID=""s62""><Data ss:Type=""String""></Data></Cell></Row>" + System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
     Else 
      'write each row data 

      For i As Integer = 0 To dt.Rows.Count - 1 
       If ((i Mod rowLimit) = 0) Then 
        'add close tags for previous sheet of the same data table 

        If ((i/rowLimit) > sheetCount) Then 
         sw.Write(System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
         sheetCount = (i/rowLimit) 
        End If 

        sw.Write((System.Environment.NewLine + System.Environment.NewLine + "<Worksheet ss:Name=""" + replaceXmlChar(dt.TableName)) + ((If(((i/rowLimit) = 0), "", "_" + Convert.ToString(i/rowLimit)))) + """>" + System.Environment.NewLine + System.Environment.NewLine + "<Table>") 


        'write column name row 
        sw.Write(System.Environment.NewLine + System.Environment.NewLine + "<Row>") 

        For Each dc In dt.Columns 
         sw.Write(String.Format("<Cell ss:StyleID=""s62""><Data ss:Type=""String"">{0}</Data></Cell>", replaceXmlChar(dc.ColumnName))) 
        Next 
        sw.Write("</Row>") 
       End If 
       sw.Write(System.Environment.NewLine + System.Environment.NewLine + "<Row>") 

       For Each dc In dt.Columns 
        sw.Write(getCell(dc.DataType, dt.Rows(i)(dc.ColumnName))) 
       Next 
       sw.Write("</Row>") 
      Next 
      sw.Write(System.Environment.NewLine + System.Environment.NewLine + "</Table>" + System.Environment.NewLine + System.Environment.NewLine + "</Worksheet>") 
     End If 
    Next 
    sw.Write("</Workbook>") 
    sw.Flush() 
    sw.Close() 
End Sub 

最后得到位置的文件,你必须保存。