iT邦幫忙

0

如何合併兩份itextsharp產生的pdf (非載入pdf再合併)

我使用itextsharp產生了2份PDF,第一份是內容,然後再產生目錄(程式碼如下)

請問要如何直接在程式後半段將兩份合併成一份PDF存檔(目錄在前,內容在後)

 Public Class itsEvents
    Inherits PdfPageEventHelper
    Public Overrides Sub OnOpenDocument(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document)
    End Sub
    Public Overrides Sub OnStartPage(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document)
    End Sub
    Public Overrides Sub OnEndPage(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document)
      Dim bf As BaseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED)
      Dim cb As PdfContentByte = writer.DirectContent
      cb.BeginText()
      cb.SetFontAndSize(bf, 10) '字型 大小
      cb.SetTextMatrix(290, 20) '位置
      cb.ShowText("- " & writer.PageNumber & " -")
      cb.EndText()
    End Sub
    Public Overrides Sub OnCloseDocument(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document)
    End Sub
End Class

Dim cList As New List(Of cPage)()
Public Class cPage
   Public Name As String
   Public Page As String
End Class

Dim _table As PdfPTable
Dim _cell As PdfPCell
Dim _chunk As iTextSharp.text.Chunk
Dim _phrase As iTextSharp.text.Phrase
Dim _paragraph As iTextSharp.text.Paragraph
Dim _tempPage As Integer = 0

Dim _Doc1 As iTextSharp.text.Document = New iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 20, 20, 50, 50)
Dim _MemoryStream1 As MemoryStream = New MemoryStream()
Dim _pdfWriter1 As PdfWriter = PdfWriter.GetInstance(_Doc1, _MemoryStream1)
Dim _ev As New itsEvents
_pdfWriter1.PageEvent = _ev
_Doc1.Open()

For i As Integer = 1 To 3
  _Doc1.NewPage()
  _table = New PdfPTable(1)
  _table.TotalWidth = 510.0F

  _phrase = New iTextSharp.text.Phrase()
  _phrase.Add("Chapter " + i.ToString)
  _table.AddCell(_phrase)
  _Doc1.Add(_table) '加入文件

  Dim _cls As New cPage
  _cls.Name = "Chapter " + i.ToString
  If i = 1 Then
    _cls.Page = 1
  Else
    _cls.Page = _tempPage
  End If
  _tempPage = _pdfWriter1.PageNumber() + 1
  cList.Add(_cls)
Next
_Doc1.Close()

Dim _Doc2 As iTextSharp.text.Document = New iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 20, 20, 50, 50)
Dim _MemoryStream2 As MemoryStream = New MemoryStream()
Dim _pdfWriter2 As PdfWriter = PdfWriter.GetInstance(_Doc2, _MemoryStream2)
_Doc2.Open()

_Doc2.NewPage()
_table = New PdfPTable(1)
_table.TotalWidth = 510.0F
_phrase = New iTextSharp.text.Phrase()
_phrase.Add("Content")
_table.AddCell(_phrase)
_Doc2.Add(_table)

_table = New PdfPTable(2)
_table.TotalWidth = 510.0F
_table.SetWidths(New Single(1) {1, 1})
For m As Integer = 0 To cList.Count - 1
  _phrase = New iTextSharp.text.Phrase()
  _phrase.Add(cList(m).Name)
  _table.AddCell(_phrase)
  _phrase = New iTextSharp.text.Phrase()
  _phrase.Add(cList(m).Page)
  _table.AddCell(_phrase)
Next
_Doc2.Add(_table)
_Doc2.Close()

'【PDF下載】
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=Merge.pdf")
Response.ContentType = "application/octet-stream"

Response.OutputStream.Write(_MemoryStream2.GetBuffer(), 0, _MemoryStream2.GetBuffer().Length)    
Response.OutputStream.Flush()
Response.OutputStream.Close()
Response.Flush()
Response.End()

1 個回答

0
海綿寶寶
iT邦大神 1 級 ‧ 2020-12-11 17:25:32

把後面的 Doc2 的部份搬到前面來
試試看可不可用

Dim cList As New List(Of cPage)()
Public Class cPage
   Public Name As String
   Public Page As String
End Class

Dim _table As PdfPTable
Dim _cell As PdfPCell
Dim _chunk As iTextSharp.text.Chunk
Dim _phrase As iTextSharp.text.Phrase
Dim _paragraph As iTextSharp.text.Paragraph
Dim _tempPage As Integer = 0

Dim _Doc1 As iTextSharp.text.Document = New iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 20, 20, 50, 50)
Dim _MemoryStream1 As MemoryStream = New MemoryStream()
Dim _pdfWriter1 As PdfWriter = PdfWriter.GetInstance(_Doc1, _MemoryStream1)
Dim _ev As New itsEvents
_pdfWriter1.PageEvent = _ev
_Doc1.Open()

'=================
_Doc1.NewPage()
_table = New PdfPTable(1)
_table.TotalWidth = 510.0F
_phrase = New iTextSharp.text.Phrase()
_phrase.Add("Content")
_table.AddCell(_phrase)
_Doc1.Add(_table)

_table = New PdfPTable(2)
_table.TotalWidth = 510.0F
_table.SetWidths(New Single(1) {1, 1})
For m As Integer = 0 To cList.Count - 1
  _phrase = New iTextSharp.text.Phrase()
  _phrase.Add(cList(m).Name)
  _table.AddCell(_phrase)
  _phrase = New iTextSharp.text.Phrase()
  _phrase.Add(cList(m).Page)
  _table.AddCell(_phrase)
Next
_Doc1.Add(_table)
'=================

For i As Integer = 1 To 3
  _Doc1.NewPage()
  _table = New PdfPTable(1)
  _table.TotalWidth = 510.0F

  _phrase = New iTextSharp.text.Phrase()
  _phrase.Add("Chapter " + i.ToString)
  _table.AddCell(_phrase)
  _Doc1.Add(_table) '加入文件

  Dim _cls As New cPage
  _cls.Name = "Chapter " + i.ToString
  If i = 1 Then
    _cls.Page = 1
  Else
    _cls.Page = _tempPage
  End If
  _tempPage = _pdfWriter1.PageNumber() + 1
  cList.Add(_cls)
Next
_Doc1.Close()

'【PDF下載】
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=Merge.pdf")
Response.ContentType = "application/octet-stream"

Response.OutputStream.Write(_MemoryStream2.GetBuffer(), 0, _MemoryStream2.GetBuffer().Length)    
Response.OutputStream.Flush()
Response.OutputStream.Close()
Response.Flush()
Response.End()
wu2960 iT邦新手 5 級 ‧ 2020-12-14 08:39:09 檢舉

這樣不行喔,
因為第一份(文件)的產生過程,才能紀錄頁碼並寫在第二份(目錄),
如果把第二份(目錄)放前面,頁碼是空的。

wu2960 iT邦新手 5 級 ‧ 2020-12-14 15:23:11 檢舉

後來我用Byte Array,再合併(如下),
但產生的PDF並不是兩份合併的結果,是哪裡錯了呢?

Dim resultChapter() As Byte
Dim resultContent() As Byte

resultChapter = _MemoryStream1.ToArray()
resultContent = _MemoryStream2.ToArray()

Dim mergedPdf(resultChapter.Length + resultContent.Length) As Byte
Array.Copy(resultContent, 0, mergedPdf, 0, resultContent.Length)
Array.Copy(resultChapter, 0, mergedPdf, resultContent.Length + 1, resultChapter.Length)

'【PDF下載】
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=Merge.pdf")
Response.ContentType = "application/octet-stream"

Response.OutputStream.Write(mergedPdf, 0, mergedPdf.Length)

Response.OutputStream.Flush()
Response.OutputStream.Close()
Response.Flush()
Response.End()

我要發表回答

立即登入回答