iTextSharp MVC Просмотр в PDF

У меня возникли небольшие проблемы с моим TextReader при попытке проанализировать строку html, которую я хочу преобразовать в PDF при использовании iTextSharp.

Function ViewDeliveryNote(ByVal id As Integer) As FileStreamResult
        'Memory buffer
        Dim ms As MemoryStream = New MemoryStream()

        'the document
        Dim document As Document = New Document(PageSize.A4)

        'the pdf writer
        PdfWriter.GetInstance(document, ms)

        Dim wc As WebClient = New WebClient
        Dim htmlText As String = wc.DownloadString("http://localhost:59800/Warehouse/DeliveryNote/" & id) 'Change to live URL
        Dim worker As html.simpleparser.HTMLWorker = New html.simpleparser.HTMLWorker(document)
        Dim reader As TextReader = New StringReader(htmlText)

        document.Open()

        worker.Open()
        worker.StartDocument()
        worker.Parse(reader)
        worker.EndDocument()
        worker.Close()

        document.Close()

        'ready the file stream
        Response.ContentType = "application/pdf"
        Response.AddHeader("content-disposition", "attachment;filename=DeliveryNote.pdf")
        Response.Buffer = True
        Response.Clear()
        Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer.Length)
        Response.OutputStream.Flush()
        Response.End()

        Return New FileStreamResult(Response.OutputStream, "application/pdf")
 End Function

Он останавливается на строке worker.Parse(reader) с ошибкой Object reference not set to an instance of an object, хотя StringReader(htmlText) успешно прочитал HTML-страницу.

Я не уверен, что я делаю неправильно или чего мне не хватает в данный момент, поэтому я был бы признателен за любую помощь.

ОБНОВЛЕНИЕ Я только что попробовал Dim reader As New StringReader(htmlText), но безрезультатно. Хотя htmlText по-прежнему определенно содержит значение, но объект считает, что это не так.


person LiamGu    schedule 05.09.2011    source источник


Ответы (1)


Я бы определенно написал для этого результат пользовательского действия, чтобы не загрязнять мой контроллер. Также следует позаботиться обо всех этих неиспользованных одноразовых ресурсах в вашем коде:

Public Class PdfResult
    Inherits ActionResult

    Private ReadOnly _id As Integer

    Public Sub New(ByVal id As Integer)
        _id = id
    End Sub

    Public Overrides Sub ExecuteResult(context As ControllerContext)
        If context Is Nothing Then
            Throw New ArgumentNullException("context")
        End If

        Dim response = context.HttpContext.Response
        response.Buffer = True
        response.ContentType = "application/pdf"
        response.AddHeader("Content-Disposition", "attachment; filename=DeliveryNote.pdf")

        Using client = New WebClient()
            Dim htmlText As String = client.DownloadString("http://localhost:59800/Warehouse/DeliveryNote/" & _id) 'Change to live URL
            Dim doc = New Document(PageSize.A4)
            PdfWriter.GetInstance(doc, response.OutputStream)
            Dim worker = New HTMLWorker(doc)
            doc.Open()
            worker.Open()
            Using reader = New StringReader(htmlText)
                worker.Parse(reader)
            End Using
            doc.Close()
        End Using
    End Sub
End Class

а потом просто:

Function ViewDeliveryNote(ByVal id As Integer) As ActionResult
    Return New PdfResult(id)
End Function

Вы также должны убедиться, что сервер имеет доступ к нужному URL-адресу. Не забывайте, что его запрос будет выполняться в контексте сетевой учетной записи, которая может не иметь тех же привилегий, что и обычные учетные записи.

person Darin Dimitrov    schedule 05.09.2011
comment
Теперь это продвинуло меня немного дальше, но когда я иду, чтобы загрузить его, файл называется передаваемым идентификатором, а затем IE говорит, что 2 не может быть загружен. - person LiamGu; 06.09.2011
comment
@Лиам, это проблема с названием файла PDF? - person Darin Dimitrov; 06.09.2011
comment
Я бы так подумал? Я предполагаю, что файл, который пытаются загрузить, будет называться DeliveryNote.pdf, а не 2 (без расширения). - person LiamGu; 06.09.2011
comment
@Liam, да, я тоже так предполагал, и именно это произошло, когда я запустил этот код: он сработал и вернул DeliveryNote.pdf в качестве имени файла. Вы убедились, что URL-адрес, который вы пытаетесь удаленно получить с помощью WebClient, действительно работает? Что происходит при отладке этого кода? Как далеко вы продвинулись в выполнении метода ExecuteResult? - person Darin Dimitrov; 06.09.2011
comment
Да, страница существует. Хотя, войдя в ExecuteResult, я столкнулся с той же проблемой. NullReferenceException на worker.Parse(reader) и точно есть доступ к URL. - person LiamGu; 06.09.2011
comment
@ Лиам, может быть, на этой странице есть что-то, что заставляет синтаксический анализатор задыхаться. Попробуйте более простую страницу. - person Darin Dimitrov; 06.09.2011
comment
Он отлично работает с гораздо более простой страницей. Поэтому я не уверен, что происходит с полной страницей, поскольку она отлично отображается в визуализаторе HTML. - person LiamGu; 07.09.2011
comment
@Liam, iTextSharp не предназначен для преобразования HTML в PDF. HTMLWorker может работать не так, как ожидалось, с более сложным HTML, который ссылается на множество внешних ресурсов, ... Лично я использую библиотеку летающих тарелок, для которой я написал сообщение в блоге здесь: bratched.com/en/home/dotnet/ - person Darin Dimitrov; 07.09.2011