ItextSharp MVC Vista a PDF
-
26-10-2019 - |
Pregunta
Tengo un pequeño problema con mi Textreader cuando intento analizar la cadena HTML que quiero convertir a PDF cuando use 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
La línea en la que se detiene es worker.Parse(reader)
con el error Object reference not set to an instance of an object
a pesar de StringReader(htmlText)
ha leído con éxito la página HTML.
No estoy seguro de lo que estoy haciendo mal o lo que me estoy perdiendo en este momento, así que estaría agradecido por cualquier ayuda.
ACTUALIZAR Acabo de intentar Dim reader As New StringReader(htmlText)
en cambio, pero fue en vano. Aunque HTMLText todavía definitivamente contiene un valor, pero el objeto piensa que no lo hace.
Solución
Definitivamente escribiría un resultado de acción personalizado para evitar contaminar mi controlador. Además, todos esos recursos desechables indispuestos en su código deben ser atendidos:
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
Y luego simplemente:
Function ViewDeliveryNote(ByVal id As Integer) As ActionResult
Return New PdfResult(id)
End Function
También debe asegurarse de que el servidor tenga acceso a la URL deseada. No olvide que su solicitud se ejecutará en el contexto de la cuenta de red que podría no tener los mismos privilegios que las cuentas normales.