我正在使用 iTextSharp 和 VB.Net 将图像标记到 PDF 文档上。(由于这不是特定于语言的,所以我也为 C# 标记了。)我有两个应用程序使用该过程。
第一个使用内存流中的字节在线显示 PDF 文档。这件作品正在工作。
第二个使用相同的功能,但将 PDF 保存到文件中。这件作品生成了一个无效的 PDF。
我见过一些类似的问题,但他们最初都是在创建一个文档,并且在代码中有一个文档对象。他们的记忆流从一开始就被破坏了。我的代码没有文档对象,并且我的原始内存流可以正常打开。
这是我得到错误的地方:(我必须将缓冲区从 m 放入一个新的内存流,因为 fillPDF 函数中的压模默认关闭流,除非另有标记。)
Dim m As MemoryStream = PDFHelper.fillPDF(filename, Nothing, markers, "")
Dim m2 As New MemoryStream(m.GetBuffer, 0, m.GetBuffer.Length)
Dim f As FileStream = New FileStream("C:\temp.pdf", FileMode.Create)
m2.CopyTo(f, m.GetBuffer.Length)
m2.Close()
f.Close()
这是我在网站上成功使用它的方法之一。这个不使用图像,尽管其他一些类似的成功地方确实在多个文档上使用图像,然后将它们合并在一起。
Dim m As System.IO.MemoryStream = PDFHelper.fillPDF(filename, New Dictionary(Of String, String), New List(Of PDFHelper.PDfImage), "SAMPLE")
Dim data As Byte() = m.GetBuffer
Response.Clear()
//Send the file to the output stream
Response.Buffer = True
//Try and ensure the browser always opens the file and doesn’t just prompt to “open/save”.
Response.AddHeader("Content-Length", data.Length.ToString())
Response.AddHeader("Content-Disposition", "inline; filename=" + "Sample")
Response.AddHeader("Expires", "0")
Response.AddHeader("Pragma", "cache")
Response.AddHeader("Cache-Control", "private")
//Set the output stream to the correct content type (PDF).
Response.ContentType = "application/pdf"
Response.AddHeader("Accept-Ranges", "bytes")
//Output the file
Response.BinaryWrite(data)
//Flushing the Response to display the serialized data to the client browser.
Response.Flush()
Try
Response.End()
Catch ex As Exception
Throw ex
End Try
这是我的实用程序类中的函数(PDFHelper.fillPDF)
Public Shared Function fillPDF(fileToFill As String, Optional fieldValues As Dictionary(Of String, String) = Nothing, Optional images As List(Of PDfImage) = Nothing, Optional watermarkText As String = "") As MemoryStream
Dim m As MemoryStream = New MemoryStream() // for storing the pdf
Dim reader As PdfReader = New PdfReader(fileToFill) // for reading the document
Dim outStamper As PdfStamper = New PdfStamper(reader, m) //for filling the document
If fieldValues IsNot Nothing Then
For Each kvp As KeyValuePair(Of String, String) In fieldValues
outStamper.AcroFields.SetField(kvp.Key, kvp.Value)
Next
End If
If images IsNot Nothing AndAlso images.Count > 0 Then //add all the images
For Each PDfImage In images
Dim img As iTextSharp.text.Image = Nothing //image to stamp
//set up the image (different for different cases
Select Case PDfImage.ImageType
//removed for brevity
End Select
Dim overContent As PdfContentByte = outStamper.GetOverContent(PDfImage.PageNumber) // specify page number for stamping
overContent.AddImage(img)
Next
End If
//add the water mark
If watermarkText <> "" Then
Dim underContent As iTextSharp.text.pdf.PdfContentByte = Nothing
Dim watermarkRect As iTextSharp.text.Rectangle = reader.GetPageSizeWithRotation(1)
//removed for brevity
End If
//flatten and close out
outStamper.FormFlattening = True
outStamper.SetFullCompression()
outStamper.Close()
reader.Close()
Return m