web-dev-qa-db-ja.com

バイト配列のリストからのPDFのiTextSharp作成

最終的なPDfとなる1つのbyte []に​​連結したいbyte []のリストを取得しました。

「ページ= copy.GetImportedPage(new PdfReader(p)、i);」で、「オブジェクト参照がインスタンスエラーに設定されていません。

私は何が起こっているのか手がかりがありません、私はすでにすべてのオブジェクトをチェックしており、nullはありません。

これに関するアイデア、またはトリックを作ることができる別のコードの断片?!

私はこの方法を持っています:

[〜#〜]編集[〜#〜]

      public static byte[] concatAndAddContent(List<byte[]> pdf)
    {
        byte [] todos;

        using(MemoryStream ms = new MemoryStream())
        {
            Document doc = new Document();
            doc.Open();

            PdfCopy copy = new PdfCopy(doc, ms);
            PdfCopyFields copy2 = new PdfCopyFields(ms);


            PdfReader reader;
            foreach (byte[] p in pdf)
            {
                reader = new PdfReader(p);
                int pages = reader.NumberOfPages;

                // loop over document pages
                for (int i = 1; i < pages; i++)
                {
                    PdfImportedPage page = copy.GetImportedPage(reader, i);
                    PdfCopy.PageStamp stamp = copy.CreatePageStamp(page);
                    PdfContentByte cb = stamp.GetUnderContent();
                    cb.SaveState();
                    stamp.AlterContents();
                    copy.AddPage(page);
                }
            }

            doc.Close();
            todos = ms.GetBuffer();
            ms.Flush();
            ms.Dispose();
        }

        return todos;
    }

スタックトレース:

[NullReferenceException: Object reference not set to an instance of an object.]
   iTextSharp.text.pdf.PdfImportedPage..ctor(PdfReaderInstance readerInstance, PdfWriter writer, Int32 pageNumber) +45
   iTextSharp.text.pdf.PdfReaderInstance.GetImportedPage(Int32 pageNumber) +175
   iTextSharp.text.pdf.PdfCopy.GetImportedPage(PdfReader reader, Int32 pageNumber) +256
   SAM.Web.Classes.UtileriasReportes.concatAndAddContent(List`1 pdf) in \Classes\UtileriasReportes.cs:199
   SAM.Web.Classes.UtileriasReportes.ObtenReporteOdt(Int32 ordenTrabajoID, Boolean caratula, Boolean juntas, Boolean cortes, Boolean materiales, Boolean resumenMateriales) 

in D:\MIMOSS\Desarrollo\SAM 2.0\Desarrollo\WebSolution\SAM.Web\Classes\UtileriasReportes.cs:168
   SAM.Web.Produccion.PopupImpresionOdt.btnImprimir_Click(Object sender, EventArgs e) in \PopupImpresionOdt.aspx.cs:44
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

御時間ありがとうございます!

16
valin077

私はそれを理解しました、それでちょうど誰もが解決策を持つことができるように:ここにあります:

    public static byte[] concatAndAddContent(List<byte[]> pdf)
    {
        byte [] all;

        using(MemoryStream ms = new MemoryStream())
        {
            Document doc = new Document();

            PdfWriter writer = PdfWriter.GetInstance(doc, ms);

            doc.SetPageSize(PageSize.LETTER);
            doc.Open();
            PdfContentByte cb = writer.DirectContent;
            PdfImportedPage page;

            PdfReader reader;
            foreach (byte[] p in pdf)
            {
                reader = new PdfReader(p);
                int pages = reader.NumberOfPages;

                // loop over document pages
                for (int i = 1; i <= pages; i++)
                {
                    doc.SetPageSize(PageSize.LETTER);
                    doc.NewPage();
                    page = writer.GetImportedPage(reader, i);
                    cb.AddTemplate(page, 0, 0);
                }
            }

            doc.Close();
            all = ms.GetBuffer();
            ms.Flush();
            ms.Dispose();
        }

        return all;
    }

お役に立てば幸いです。

41
valin077

これは機能します:

使用 iTextSharp-LGPL 4.1.6:

    public static byte[] ConcatenatePdfs(IEnumerable<byte[]> documents)
    {
        using (var ms = new MemoryStream())
        {
            var outputDocument = new Document();
            var writer = new PdfCopy(outputDocument, ms);
            outputDocument.Open();

            foreach (var doc in documents)
            {
                var reader = new PdfReader(doc);
                for (var i = 1; i <= reader.NumberOfPages; i++)
                {
                    writer.AddPage(writer.GetImportedPage(reader, i));
                }
                writer.FreeReader(reader);
                reader.Close();
            }

            writer.Close();
            outputDocument.Close();
            var allPagesContent = ms.GetBuffer();
            ms.Flush();

            return allPagesContent;
        }
    }
4
Nina

私は最初に上記の回答を使用していましたが、PDFは非常に大きかったです。この問題を完全に解決したこのリンクをもう一度提供し、大きな問題を解決するのに役立つと思いました。PDF私。

https://stackoverflow.com/a/6752769

0
Mike Wallace

これで修正できるかどうかはわかりませんが、ゼロではなく1ページ目からGetImportedPageを初期化してみてくださいint i = 1 forループ内。このような:

// loop over document pages 
//was (int i = 0; i < pages; i++) {
for (int i = 1; i < pages; i++) {
    page = copy.GetImportedPage(new PdfReader(p), i);
    stamp = copy.CreatePageStamp(page);
    PdfContentByte cb = stamp.GetUnderContent();
    cb.SaveState();
    stamp.AlterContents();
    copy.AddPage(page);
}
0
Jay Riggs

このソリューションはiText 7.1.8で機能します。

以前の回答と新しい APIの例 に基づいています

    public static byte[] MergePDFs(List<byte[]> lPdfByteContent)
    {
        using (MemoryStream oMemoryStream = new MemoryStream())
        {
            using (PdfWriter oWriter = new PdfWriter(oMemoryStream))
            {
                oWriter.SetSmartMode(true);

                using (PdfDocument oMergedPdf = new PdfDocument(oWriter))
                {
                    PdfMerger oMerger = new PdfMerger(oMergedPdf, false, false);

                    for (int i = 0; i < lPdfByteContent.Count; i++)
                    {
                        PdfDocument oPdfAux = new PdfDocument(new PdfReader(new MemoryStream(lPdfByteContent[i])));
                        oMerger.SetCloseSourceDocuments(true).Merge(oPdfAux, 1, oPdfAux.GetNumberOfPages());
                    }
                }
            }
            return oMemoryStream.ToArray();
        }
    }
0
Andre Noivo

Itextsharpのコードを見ても、同じコンテンツの複数のリーダーで常に機能するとは限りません。

やってみることをお勧めします

page = copy.GetImportedPage(reader, i);

読みたいページごとに新しいリーダーを作成するのではなく、.

更新:助けになるかどうかわかりませんが

コードをコピーして貼り付けたところ、NullReferenceExceptionが発生しましたが、この行のみです

 stamp.AlterContents();

それはあなたがそれを得ている場所の後であるので、それは奇妙です。+

リストの悪いコンテンツを渡すと、欠落しているPDFヘッダー、トレーラーが見つかりませんなど)を生成できたので、pのコンテンツの違いはないと思います

VS 2008に組み込まれているソースコードバージョンでバージョン5.0.4を使用しています。クライアントはvs 2010です。おそらく、これらが違いを説明しています。

0
Conrad Frix