itextsharp pdfsmartcopy只返回最后一页

时间:2014-08-13 16:02:30

标签: asp.net pdf itextsharp memorystream pdfstamper

我遇到的问题是只存储了我的pdf的最后一页。

pdf应该是多页长,如果我只是使用Response和mms内存流将pdf发送到浏览器,这可以正常工作,但是我需要将它作为pdf添加到电子邮件中,因此正在编写mms到创建电子邮件附件时创建新内存流的字节数。这是为了解决闭合流错误。

这是我的代码

 Public Shared Function SendPrePackLabels(ByVal bf_id As String, mail As String) As Boolean
        Dim pars(0) As SqlParameter
        pars(0) = New SqlParameter("@bf_id", SqlDbType.VarChar) With {.Value = bf_id}

        Dim p As String
        Dim reader As PdfReader
        Dim mms As New MemoryStream

        Dim rt() As Byte
        Dim i As Integer = 0

        Using dc As Document = New Document
            Using sc As PdfSmartCopy = New PdfSmartCopy(dc, System.Web.HttpContext.Current.Response.OutputStream)
                dc.Open()
                With SqlHelper.ExecuteDataset(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spPrepack_Labels", pars).Tables(0)
                    For Each dr As DataRow In .Rows
                        Dim pdfr As New PdfReader("http://192.168.0.221/template.pdf")
                        Using ms As New MemoryStream
                            Using pdfs As New PdfStamper(pdfr, ms)
                                Dim fields As AcroFields = pdfs.AcroFields
                                fields.GenerateAppearances = True
                                fields.SetField("pono", dr.Item("po_no").ToString)
                                fields.SetField("ref", dr.Item("alt_code").ToString)
                                fields.SetField("colour", dr.Item("colour").ToString)
                                fields.SetField("code", dr.Item("sizerun_hdr_id").ToString)

                                For k As Integer = 1 To dr.Table.Columns.Count - 6
                                    Dim j As Integer = k + 5
                                    fields.SetField("s" & k, dr.Table.Columns(j).ColumnName.ToString)
                                    If dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString = "" Then
                                        p = "0"
                                    Else
                                        p = dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString
                                    End If
                                    fields.SetField("p" & k, p)
                                Next
                                fields.SetField("pack", dr.Item("sizerun_hdr_id").ToString)
                                Dim bcfont As BaseFont = BaseFont.CreateFont("http://192.168.0.221/ean.ttf", BaseFont.CP1252, BaseFont.EMBEDDED)
                                fields.SetFieldProperty("barcode", "textfont", bcfont, Nothing)
                                fields.SetFieldProperty("barcode", "textsize", 60.0F, Nothing)


                                Dim mBarcode As String = "219" & dr.Item("sizerun_hdr_id").ToString
                                Dim cLength As Integer = mBarcode.Length

                                Dim zerostoadd As Integer = 12 - cLength
                                Dim digit12barcode As String = mBarcode.PadRight(12, CChar("0"))
                                Dim FinalBarcode As String = returnCheckDigitedBarcode(digit12barcode)
                                fields.SetField("barcode", FinalBarcode)


                                Dim par(1) As SqlParameter
                                par(0) = New SqlParameter("@sizerun_hdr_id", SqlDbType.VarChar) With {.Value = dr.Item("sizerun_hdr_id").ToString}
                                par(1) = New SqlParameter("@ean13", SqlDbType.VarChar) With {.Value = FinalBarcode}

                                SqlHelper.ExecuteScalar(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spSizeRunEAN13", par)
                                pdfs.FormFlattening = True
                                ms.Flush()
                            End Using
                            reader = New PdfReader(ms.ToArray)
                            sc.AddPage(sc.GetImportedPage(reader, 1))
                            mms = ms
                        End Using
                    Next
                End With
            End Using
        End Using

        Dim bt() As Byte = mms.ToArray

        Try
            If mail.Length > 0 Then
                Dim eMsg As New MailMessage()

                eMsg.From = New MailAddress("myemail@mydomain.co.uk")
                eMsg.To.Add(New MailAddress(mail))


                Dim title As String = "<h3>Here are the Prepack Labels.</h3>"

                eMsg.Subject = "Prepack Labels"
                eMsg.Body = "<html>" & title & "</html>"
                eMsg.IsBodyHtml = True

                Dim att As Attachment = New Attachment(New MemoryStream(bt), "Prepack Labels.pdf", "application/pdf")
                eMsg.Attachments.Add(att)

                Dim SMTP1 As New SmtpClient
                SMTP1.Host = "EX"
                SMTP1.Send(eMsg)

                att.Dispose()
            End If
            Return True
        Catch ex As Exception
            Return False
        End Try
       End Function

1 个答案:

答案 0 :(得分:0)

我不确定你的确切问题,但我很确定如果你把巨大的功能分解成只做一件事的更小的更具体的功能,你的生活会更容易。另外,我真的建议永远不要写入原始的ASP.Net流,直到之后你创建了一个PDF。相反,总是写一个MemoryStream,抓住字节并用它们做点什么。

下面的代码将其分为四个函数。 CreatePdf()遍历数据库,并为表格中的每一行调用CreateSinglePdf(),并将其与PdfSmartCopy合并。 SendEmail()完全没有意识到iTextSharp,只是接收一个假定为PDF的原始字节数组。这一切都是由SendPrePackLabels()启动的,您可能还需要Response.BinaryWrite()您的字节。

Public Shared Function SendPrePackLabels(ByVal bf_id As String, mail As String) As Boolean
    Dim bt = CreatePdf(bf_id)
    Return SendEmail(bt, mail)
End Function
Public Shared Function CreateSinglePdf(dr As DataRow) As Byte()
    Using ms As New MemoryStream
        Using pdfr As New PdfReader("http://192.168.0.221/template.pdf")
            Using pdfs As New PdfStamper(pdfr, ms)
                Dim fields As AcroFields = pdfs.AcroFields
                fields.GenerateAppearances = True
                fields.SetField("pono", dr.Item("po_no").ToString)
                fields.SetField("ref", dr.Item("alt_code").ToString)
                fields.SetField("colour", dr.Item("colour").ToString)
                fields.SetField("code", dr.Item("sizerun_hdr_id").ToString)

                Dim p As String

                For k As Integer = 1 To dr.Table.Columns.Count - 6
                    Dim j As Integer = k + 5
                    fields.SetField("s" & k, dr.Table.Columns(j).ColumnName.ToString)
                    If dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString = "" Then
                        p = "0"
                    Else
                        p = dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString
                    End If
                    fields.SetField("p" & k, p)
                Next
                fields.SetField("pack", dr.Item("sizerun_hdr_id").ToString)
                Dim bcfont As BaseFont = BaseFont.CreateFont("http://192.168.0.221/ean.ttf", BaseFont.CP1252, BaseFont.EMBEDDED)
                fields.SetFieldProperty("barcode", "textfont", bcfont, Nothing)
                fields.SetFieldProperty("barcode", "textsize", 60.0F, Nothing)


                Dim mBarcode As String = "219" & dr.Item("sizerun_hdr_id").ToString
                Dim cLength As Integer = mBarcode.Length

                Dim zerostoadd As Integer = 12 - cLength
                Dim digit12barcode As String = mBarcode.PadRight(12, CChar("0"))
                Dim FinalBarcode As String = returnCheckDigitedBarcode(digit12barcode)
                fields.SetField("barcode", FinalBarcode)


                Dim par(1) As SqlParameter
                par(0) = New SqlParameter("@sizerun_hdr_id", SqlDbType.VarChar) With {.Value = dr.Item("sizerun_hdr_id").ToString}
                par(1) = New SqlParameter("@ean13", SqlDbType.VarChar) With {.Value = FinalBarcode}

                SqlHelper.ExecuteScalar(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spSizeRunEAN13", par)
                pdfs.FormFlattening = True
            End Using
        End Using

        Return ms.ToArray()
    End Using
End Function
Public Shared Function CreatePdf(ByVal bf_id As String) As Byte()
    Dim pars(0) As SqlParameter
    pars(0) = New SqlParameter("@bf_id", SqlDbType.VarChar) With {.Value = bf_id}


    Using ms As New System.IO.MemoryStream
        Using dc As Document = New Document
            Using sc As PdfSmartCopy = New PdfSmartCopy(dc, ms)
                dc.Open()
                With SqlHelper.ExecuteDataset(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spPrepack_Labels", pars).Tables(0)
                    For Each dr As DataRow In .Rows

                        Dim pageBytes = CreateSinglePdf(dr)

                        Using reader = New PdfReader(pageBytes)
                            sc.AddPage(sc.GetImportedPage(reader, 1))
                        End Using
                    Next
                End With
            End Using
        End Using

        Return ms.ToArray()
    End Using
End Function

Public Shared Function SendEmail(bt As Byte(), mail As String) As Boolean
    Try
        If mail.Length > 0 Then
            Dim eMsg As New MailMessage()

            eMsg.From = New MailAddress("myemail@mydomain.co.uk")
            eMsg.To.Add(New MailAddress(mail))


            Dim title As String = "<h3>Here are the Prepack Labels.</h3>"

            eMsg.Subject = "Prepack Labels"
            eMsg.Body = "<html>" & title & "</html>"
            eMsg.IsBodyHtml = True

            Dim att As Attachment = New Attachment(New MemoryStream(bt), "Prepack Labels.pdf", "application/pdf")
            eMsg.Attachments.Add(att)

            Dim SMTP1 As New SmtpClient
            SMTP1.Host = "EX"
            SMTP1.Send(eMsg)

            att.Dispose()
        End If
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function