SQL Serverデータベースに11列、500,000行以上のテーブルがあり、.PDF
ドキュメントに保存する必要があります。C#でデータベースから多くのデータをpdfに読み込む方法
私はasp.net Webアプリケーション "MigraDoc"で使用しますが、PdfDocumentRenderer
のドキュメントの作成中に "OutOfMemory"例外が発生します。
ハードウェアをアップグレードすることなく大量のデータを.pdf
に保存する方法はありますか?
SQL Serverデータベースに11列、500,000行以上のテーブルがあり、.PDF
ドキュメントに保存する必要があります。C#でデータベースから多くのデータをpdfに読み込む方法
私はasp.net Webアプリケーション "MigraDoc"で使用しますが、PdfDocumentRenderer
のドキュメントの作成中に "OutOfMemory"例外が発生します。
ハードウェアをアップグレードすることなく大量のデータを.pdf
に保存する方法はありますか?
データを部品単位で取得してください。 EFを使用すると、次のようになります。
var pathToFile = "D:\\example.pdf";
var pdfDoc = new PdfDoc(pathToFile); //change it to library that you use for Pdf
using (var db = new DatabaseContext())
{
var fetchCount = 100000; //take size that your hardware can handle with
var rowCount = db.YourTableName.Count();
double stepsCount = (rowCount + 0.0)/fetchCount;
for (int i = 0; i < rowCount/fetchCount; i++)
{
var rowsToAdd = db.YourTableName.Skip(i*fetchCount).Take(fetchCount);
pdfDoc.Append(rowsToAdd); //Use your library method
}
}
希望します。
はい、動作します。ここに私の例があります。 'var skip = 0; var take = ListWithAllData.Count-skip> 50000? 50000:ListWithAllData.Count; do { AddDataTable(ref pdfDoc、ListWithAllData.Skip(skip).Take(take)); skip + = take; take = ListWithAllData.Count - 50000をスキップしますか? 50000:ListWithAllData.Count - スキップします。 } while(skip!= ListWithAllData.Count); ' –
私は前に同様の問題に取り組んできました。私はあなたが現在OutOfMemory例外の結果、データテーブルにすべてのデータを格納していると言って野生の推測をしていますか?
ベスト・アプローチは、データ・リーダーを使用することです。その後、データをストリーミングして、行ごとにPDFにレコードを追加することができます。
これが役に立ちます。がんばろう。
次のコードを使用できます。私はPDF文書に500,000行を書いています。 ITextSharpの使用を忘れないでください。
Sub ExportGridViewToPDF(Response As HttpResponse, ReportTitle As String, SubTitle As String)
Response.ClearContent()
Response.ContentType = "application/pdf"
Response.AddHeader("content-disposition", "attachment;filename=test.pdf")
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Dim pdfDoc As New Document(PageSize.LETTER, 10.0F, 10.0F, 10.0F, 0.0F)
Dim htmlparser As New HTMLWorker(pdfDoc)
PdfWriter.GetInstance(pdfDoc, Response.OutputStream)
pdfDoc.Open()
Dim c As New Chunk(ReportTitle & vbLf, FontFactory.GetFont("Segoe UI", 14))
Dim p As New Paragraph()
p.Alignment = Element.ALIGN_CENTER
p.Add(c)
Dim chunk1 As New Chunk(SubTitle & vbLf, FontFactory.GetFont("Segoe UI", 8))
Dim empty As New Chunk(" ")
Dim p1 As New Paragraph()
p1.Alignment = Element.ALIGN_LEFT
p1.Font.SetStyle("underline")
p1.Add(chunk1)
pdfDoc.Add(p)
pdfDoc.Add(p1)
pdfDoc.Add(empty)
Dim sb As New StringBuilder()
sb.Append(" <table>")
sb.Append("<tr>")
sb.Append("<th>test</th>")
sb.Append("</tr>")
For i As Integer = 0 To 500000
sb.Append("<tr><td>" & i & "</td></tr>")
Next
sb.Append("</table>")
For i As Integer = 0 To 1000
Threading.Thread.Sleep(1)
Next
Dim sr As New StringReader(sb.ToString())
htmlparser.Parse(sr)
pdfDoc.Close()
Response.Write(pdfDoc)
Response.End()
End Sub
Private Sub test_Click(sender As Object, e As EventArgs) Handles test.Click
ExportGridViewToPDF(Response, "test", "sub title")
End Sub
トリックは、ループのために、以下である:繰り返し秒間のスレッドを眠っによって
For i As Integer = 0 To 1000
Threading.Thread.Sleep(1)
Next
は、システムリソースへの一時的な救済を与えるだろうと「System.OutOfMemoryExceptionに」例外を停止します。 SQLDataReaderを使用して、データベースからレコードをフェッチできます。 SQLDataReaderは転送専用なので、データベースからデータを取得する方が高速です。
StringReaderは常にExceptionを返します**例でも "不正な文字" **がありますが、for-loopとITextSharpは役に立ちました。私はそれを使用し、 '.Skip(スキップ).Take(take)'を使って問題を解決します –
ストアドプロシージャを作成すると、返された最後の主キーを追跡しながら、小さな増分でデータを返しますか?あなたはインクリメント/チャンクでこれを行う必要があります。500,000は一度に試して取得する行がたくさんあります。私はまた 'ITextSharp.dll'を見て、pdfも作成することをお勧めします。 – MethodMan
あなたはおそらくPDFあなたのライブラリがそれをサポートしていれば、それをディスク上に作成する必要があります。 – bmm6o