我使用通过数据集传递的XML Excel生成一个Excel报告。
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 :(得分:0)
最后我以简单的方式解决了我的问题。
我希望你能回答这个问题。
我的场景我正在使用Stringwriter从数据集中编写数据。当我的数据集包含超过20000条记录时,它会抛出一个错误“System.outofmeory exception”。 因为Stringwriter会将您的数据保存在虚拟内存(RAM)中。
所以,我使用的是Streamwriter而不是Stringwriter。
第1步:
我最初用标题创建了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()
第二步:
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
最后从您保存的位置获取文件。