Sometimes it’s necessary to customize the content of a document on the fly from templates. There’s various different ways this can be done, but one way is to have a template with different content on each page of a document and then based on certain criteria (i.e. content from page 1, 5, 8 is required to be combined) you can combine this content into one page using The CapturePage and DrawCapturedPage functions. This also allows you to add footers/headers and other template content.
Here is some sample code written Visual Basic .NET which demonstrates how to determine the content position / height for a page (using pixel analysis) and then draw that content onto the one page in a way that does not overlay the content on other content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
Public Class Form1 Private Sub btnMergePageContent_Click(sender As Object, e As EventArgs) Handles btnMergePageContent.Click Dim QP As New DebenuPDFLibraryAX1113.PDFLibrary If QP.UnlockKey("...") = 1 Then If QP.LoadFromFile("C:\temp\mutli_page_content.pdf", "") = 1 Then ' Remember the original page count Dim pageCount = QP.PageCount() ' First create a new page at the end of the document QP.NewPage() QP.SetPageSize("Letter") ' Measure the height of all the pages (but not the new blank page) Dim pageHeight(pageCount) As Double For page As Integer = 1 To pageCount QP.SelectPage(page) pageHeight(page - 1) = MeasurePageContentHeight(QP) Next ' Capture all the pages (but not the new blank page) Dim captureID(pageCount) As Integer For page As Integer = 1 To pageCount ' Capture page 1 each time because the pages are ' removed from the document as they are captured captureID(page - 1) = QP.CapturePage(1) Next ' Set the origin to the top of the page QP.SetOrigin(1) ' Draw pages 6, 1, 3, 5 and then 9 Dim pagesToDraw() As Integer = {6, 1, 3, 5, 9} Dim currentPosition As Double = 0 For thisPageIndex As Integer = 1 To UBound(pagesToDraw) ' Look up the page number in the pagesToDraw array Dim thisPageNumber As Integer = pagesToDraw(thisPageIndex - 1) ' Draw the captured page (use the full height) QP.DrawCapturedPage(captureID(thisPageNumber - 1), 0, currentPosition, QP.PageWidth(), QP.PageHeight()) ' Increase the current position currentPosition = currentPosition + pageHeight(thisPageNumber - 1) Next QP.SaveToFile("C:\temp\content.pdf") End If End If End Sub ' Measures the height of the page content in the current measurement units Private Function MeasurePageContentHeight(PDFLibrary As DebenuPDFLibraryAX1113.PDFLibrary) As Double Dim Result As Double = 0 Dim bmpBytes() As Byte = PDFLibrary.RenderPageToVariant(96, PDFLibrary.SelectedPage, 0) Dim bmpStream As New System.IO.MemoryStream(bmpBytes) Dim BMP As New Bitmap(bmpStream) ' Lock the bitmap's bits Dim rect As New Rectangle(0, 0, BMP.Width, BMP.Height) Dim bmpData As System.Drawing.Imaging.BitmapData = BMP.LockBits(rect, _ Drawing.Imaging.ImageLockMode.ReadOnly, BMP.PixelFormat) ' Get the address of the first line Dim ptr As IntPtr = bmpData.Scan0 Dim foundPixels = False Dim row = BMP.Height ' Declare an array to hold the bytes of the bitmap Dim bytes As Integer = Math.Abs(bmpData.Stride) * BMP.Height Dim rgbValues(bytes - 1) As Byte ' Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes) Dim byteOffset = (BMP.Height - 1) * bmpData.Stride While (Not foundPixels) And (row > 0) row = row - 1 ' Set every third value to 255. A 24bpp image will look red. For counter As Integer = 0 To bmpData.Stride - 1 If (rgbValues(byteOffset + counter) <> 255) Then foundPixels = True End If Next byteOffset = byteOffset - bmpData.Stride End While ' Unlock the bits BMP.UnlockBits(bmpData) If (foundPixels) Then Result = (PDFLibrary.PageHeight() * row) / BMP.Height() End If MeasurePageContentHeight = Result End Function End Class |
Private Sub btnMergePageContent_Click(sender As Object, e As EventArgs) Handles btnMergePageContent.Click
Dim QP As New DebenuPDFLibraryAX1113.PDFLibrary
If QP.UnlockKey("...") = 1 Then
If QP.LoadFromFile("C:\temp\mutli_page_content.pdf", "") = 1 Then
' Remember the original page count
Dim pageCount = QP.PageCount()
' First create a new page at the end of the document
QP.NewPage()
QP.SetPageSize("Letter")
' Measure the height of all the pages (but not the new blank page)
Dim pageHeight(pageCount) As Double
For page As Integer = 1 To pageCount
QP.SelectPage(page)
pageHeight(page - 1) = MeasurePageContentHeight(QP)
Next
' Capture all the pages (but not the new blank page)
Dim captureID(pageCount) As Integer
For page As Integer = 1 To pageCount
' Capture page 1 each time because the pages are
' removed from the document as they are captured
captureID(page - 1) = QP.CapturePage(1)
Next
' Set the origin to the top of the page
QP.SetOrigin(1)
' Draw pages 6, 1, 3, 5 and then 9
Dim pagesToDraw() As Integer = {6, 1, 3, 5, 9}
Dim currentPosition As Double = 0
For thisPageIndex As Integer = 1 To UBound(pagesToDraw)
' Look up the page number in the pagesToDraw array
Dim thisPageNumber As Integer = pagesToDraw(thisPageIndex - 1)
' Draw the captured page (use the full height)
QP.DrawCapturedPage(captureID(thisPageNumber - 1), 0, currentPosition, QP.PageWidth(), QP.PageHeight())
' Increase the current position
currentPosition = currentPosition + pageHeight(thisPageNumber - 1)
Next
QP.SaveToFile("C:\temp\content.pdf")
End If
End If
End Sub
' Measures the height of the page content in the current measurement units
Private Function MeasurePageContentHeight(PDFLibrary As DebenuPDFLibraryAX1113.PDFLibrary) As Double
Dim Result As Double = 0
Dim bmpBytes() As Byte = PDFLibrary.RenderPageToVariant(96, PDFLibrary.SelectedPage, 0)
Dim bmpStream As New System.IO.MemoryStream(bmpBytes)
Dim BMP As New Bitmap(bmpStream)
' Lock the bitmap's bits
Dim rect As New Rectangle(0, 0, BMP.Width, BMP.Height)
Dim bmpData As System.Drawing.Imaging.BitmapData = BMP.LockBits(rect, _
Drawing.Imaging.ImageLockMode.ReadOnly, BMP.PixelFormat)
' Get the address of the first line
Dim ptr As IntPtr = bmpData.Scan0
Dim foundPixels = False
Dim row = BMP.Height
' Declare an array to hold the bytes of the bitmap
Dim bytes As Integer = Math.Abs(bmpData.Stride) * BMP.Height
Dim rgbValues(bytes - 1) As Byte
' Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
Dim byteOffset = (BMP.Height - 1) * bmpData.Stride
While (Not foundPixels) And (row > 0)
row = row - 1
' Set every third value to 255. A 24bpp image will look red.
For counter As Integer = 0 To bmpData.Stride - 1
If (rgbValues(byteOffset + counter) <> 255) Then
foundPixels = True
End If
Next
byteOffset = byteOffset - bmpData.Stride
End While
' Unlock the bits
BMP.UnlockBits(bmpData)
If (foundPixels) Then
Result = (PDFLibrary.PageHeight() * row) / BMP.Height()
End If
MeasurePageContentHeight = Result
End Function
End Class