2017-05-12 9 views
0

SQL Serverデータベースに11列、500,000行以上のテーブルがあり、.PDFドキュメントに保存する必要があります。C#でデータベースから多くのデータをpdfに読み込む方法

私はasp.net Webアプリケーション "MigraDoc"で使用しますが、PdfDocumentRendererのドキュメントの作成中に "OutOfMemory"例外が発生します。

ハードウェアをアップグレードすることなく大量のデータを.pdfに保存する方法はありますか?

+0

ストアドプロシージャを作成すると、返された最後の主キーを追跡しながら、小さな増分でデータを返しますか?あなたはインクリメント/チャンクでこれを行う必要があります。500,000は一度に試して取得する行がたくさんあります。私はまた 'ITextSharp.dll'を見て、pdfも作成することをお勧めします。 – MethodMan

+0

あなたはおそらくPDFあなたのライブラリがそれをサポートしていれば、それをディスク上に作成する必要があります。 – bmm6o

答えて

0

データを部品単位で取得してください。 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 
    } 
} 

希望します。

+0

はい、動作します。ここに私の例があります。 '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); ' –

0

私は前に同様の問題に取り組んできました。私はあなたが現在OutOfMemory例外の結果、データテーブルにすべてのデータを格納していると言って野生の推測をしていますか?

ベスト・アプローチは、データ・リーダーを使用することです。その後、データをストリーミングして、行ごとにPDFにレコードを追加することができます。

これが役に立ちます。がんばろう。

0

次のコードを使用できます。私は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は転送専用なので、データベースからデータを取得する方が高速です。

+0

StringReaderは常にExceptionを返します**例でも "不正な文字" **がありますが、for-loopとITextSharpは役に立ちました。私はそれを使用し、 '.Skip(スキップ).Take(take)'を使って問題を解決します –

関連する問題