0

我有一个问题,只存储了我的 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
4

1 回答 1

0

我不确定你的确切问题,但我很确定如果你将巨大的功能分解成只做一件事的更小的更具体的功能,你的生活会更轻松。此外,我真的建议您在创建 PDF之前不要写入原始 ASP.Net 流。相反,始终写入 a 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
于 2014-08-14T11:34:40.087 回答