This repository has been archived by the owner on Jul 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 92
A VB version
东方孤思子 Paris·QianSen edited this page Mar 3, 2017
·
1 revision
I have ported 0.5.7 version to Virtual Basic.
For anyone who may need it, you can take it as a reference.
Imports System.Text
Imports System.IO
Imports System.Threading
Imports System.Configuration
Namespace Codaxy.WkHtmlToPdf
Public Class PdfConvertException
Inherits Exception
Public Sub New(msg As String)
MyBase.New(msg)
End Sub
End Class
Public Class PdfConvertTimeoutException
Inherits PdfConvertException
Public Sub New()
MyBase.New("HTML to PDF conversion process has not finished in the given period.")
End Sub
End Class
Public Class PdfOutput
Public Property OutputFilePath() As String
Get
Return m_OutputFilePath
End Get
Set
m_OutputFilePath = Value
End Set
End Property
Private m_OutputFilePath As String
Public Property OutputStream() As Stream
Get
Return m_OutputStream
End Get
Set
m_OutputStream = Value
End Set
End Property
Private m_OutputStream As Stream
Public Property OutputCallback() As Action(Of PdfDocument, Byte())
Get
Return m_OutputCallback
End Get
Set
m_OutputCallback = Value
End Set
End Property
Private m_OutputCallback As Action(Of PdfDocument, Byte())
End Class
Public Class PdfDocument
Public Property Url() As String
Get
Return m_Url
End Get
Set
m_Url = Value
End Set
End Property
Private m_Url As String
Public Property Html() As String
Get
Return m_Html
End Get
Set
m_Html = Value
End Set
End Property
Private m_Html As String
Public Property HeaderUrl() As String
Get
Return m_HeaderUrl
End Get
Set
m_HeaderUrl = Value
End Set
End Property
Private m_HeaderUrl As String
Public Property FooterUrl() As String
Get
Return m_FooterUrl
End Get
Set
m_FooterUrl = Value
End Set
End Property
Private m_FooterUrl As String
Public Property HeaderLeft() As String
Get
Return m_HeaderLeft
End Get
Set
m_HeaderLeft = Value
End Set
End Property
Private m_HeaderLeft As String
Public Property HeaderCenter() As String
Get
Return m_HeaderCenter
End Get
Set
m_HeaderCenter = Value
End Set
End Property
Private m_HeaderCenter As String
Public Property HeaderRight() As String
Get
Return m_HeaderRight
End Get
Set
m_HeaderRight = Value
End Set
End Property
Private m_HeaderRight As String
Public Property FooterLeft() As String
Get
Return m_FooterLeft
End Get
Set
m_FooterLeft = Value
End Set
End Property
Private m_FooterLeft As String
Public Property FooterCenter() As String
Get
Return m_FooterCenter
End Get
Set
m_FooterCenter = Value
End Set
End Property
Private m_FooterCenter As String
Public Property FooterRight() As String
Get
Return m_FooterRight
End Get
Set
m_FooterRight = Value
End Set
End Property
Private m_FooterRight As String
Public Property State() As Object
Get
Return m_State
End Get
Set
m_State = Value
End Set
End Property
Private m_State As Object
Public Property Cookies() As Dictionary(Of String, String)
Get
Return m_Cookies
End Get
Set
m_Cookies = Value
End Set
End Property
Private m_Cookies As Dictionary(Of String, String)
Public Property ExtraParams() As Dictionary(Of String, String)
Get
Return m_ExtraParams
End Get
Set
m_ExtraParams = Value
End Set
End Property
Private m_ExtraParams As Dictionary(Of String, String)
End Class
Public Class PdfConvertEnvironment
Public Property TempFolderPath() As String
Get
Return m_TempFolderPath
End Get
Set
m_TempFolderPath = Value
End Set
End Property
Private m_TempFolderPath As String
Public Property WkHtmlToPdfPath() As String
Get
Return m_WkHtmlToPdfPath
End Get
Set
m_WkHtmlToPdfPath = Value
End Set
End Property
Private m_WkHtmlToPdfPath As String
Public Property Timeout() As Integer
Get
Return m_Timeout
End Get
Set
m_Timeout = Value
End Set
End Property
Private m_Timeout As Integer
Public Property Debug() As Boolean
Get
Return m_Debug
End Get
Set
m_Debug = Value
End Set
End Property
Private m_Debug As Boolean
End Class
Public Class PdfConvert
Shared _e As PdfConvertEnvironment
Public Shared ReadOnly Property Environment() As PdfConvertEnvironment
Get
If _e Is Nothing Then
_e = New PdfConvertEnvironment() With {
.TempFolderPath = Path.GetTempPath(),
.WkHtmlToPdfPath = GetWkhtmlToPdfExeLocation(),
.Timeout = 60000
}
End If
Return _e
End Get
End Property
Private Shared Function GetWkhtmlToPdfExeLocation() As String
Dim filePath As String, customPath As String = ConfigurationManager.AppSettings("wkhtmltopdf:path")
If customPath IsNot Nothing Then
filePath = Path.Combine(customPath, "wkhtmltopdf.exe")
If File.Exists(filePath) Then
Return filePath
End If
End If
Dim programFilesPath As String = System.Environment.GetEnvironmentVariable("ProgramFiles")
filePath = Path.Combine(programFilesPath, "wkhtmltopdf\wkhtmltopdf.exe")
If File.Exists(filePath) Then
Return filePath
End If
Dim programFilesx86Path As String = System.Environment.GetEnvironmentVariable("ProgramFiles(x86)")
filePath = Path.Combine(programFilesx86Path, "wkhtmltopdf\wkhtmltopdf.exe")
If File.Exists(filePath) Then
Return filePath
End If
filePath = Path.Combine(programFilesPath, "wkhtmltopdf\bin\wkhtmltopdf.exe")
If File.Exists(filePath) Then
Return filePath
End If
Return Path.Combine(programFilesx86Path, "wkhtmltopdf\bin\wkhtmltopdf.exe")
End Function
Public Shared Sub ConvertHtmlToPdf(document As PdfDocument, output As PdfOutput)
ConvertHtmlToPdf(document, Nothing, output)
End Sub
Public Shared Sub ConvertHtmlToPdf(document As PdfDocument, environment As PdfConvertEnvironment, woutput As PdfOutput)
If environment Is Nothing Then
environment = PdfConvert.Environment
End If
If document.Html IsNot Nothing Then
document.Url = "-"
End If
Dim outputPdfFilePath As String
Dim delete As Boolean
If woutput.OutputFilePath IsNot Nothing Then
outputPdfFilePath = woutput.OutputFilePath
delete = False
Else
outputPdfFilePath = Path.Combine(environment.TempFolderPath, String.Format("{0}.pdf", Guid.NewGuid()))
delete = True
End If
If Not File.Exists(environment.WkHtmlToPdfPath) Then
Throw New PdfConvertException(String.Format("File '{0}' not found. Check if wkhtmltopdf application is installed.", environment.WkHtmlToPdfPath))
End If
Dim paramsBuilder As New StringBuilder()
paramsBuilder.Append("--page-size A4 ")
If Not String.IsNullOrEmpty(document.HeaderUrl) Then
paramsBuilder.AppendFormat("--header-html {0} ", document.HeaderUrl)
paramsBuilder.Append("--margin-top 25 ")
paramsBuilder.Append("--header-spacing 5 ")
End If
If Not String.IsNullOrEmpty(document.FooterUrl) Then
paramsBuilder.AppendFormat("--footer-html {0} ", document.FooterUrl)
paramsBuilder.Append("--margin-bottom 25 ")
paramsBuilder.Append("--footer-spacing 5 ")
End If
If Not String.IsNullOrEmpty(document.HeaderLeft) Then
paramsBuilder.AppendFormat("--header-left ""{0}"" ", document.HeaderLeft)
End If
If Not String.IsNullOrEmpty(document.HeaderCenter) Then
paramsBuilder.AppendFormat("--header-center ""{0}"" ", document.HeaderCenter)
End If
If Not String.IsNullOrEmpty(document.HeaderRight) Then
paramsBuilder.AppendFormat("--header-right ""{0}"" ", document.HeaderRight)
End If
If Not String.IsNullOrEmpty(document.FooterLeft) Then
paramsBuilder.AppendFormat("--footer-left ""{0}"" ", document.FooterLeft)
End If
If Not String.IsNullOrEmpty(document.FooterCenter) Then
paramsBuilder.AppendFormat("--footer-center ""{0}"" ", document.FooterCenter)
End If
If Not String.IsNullOrEmpty(document.FooterRight) Then
paramsBuilder.AppendFormat("--footer-right ""{0}"" ", document.FooterRight)
End If
If document.ExtraParams IsNot Nothing Then
For Each extraParam In document.ExtraParams
paramsBuilder.AppendFormat("--{0} {1} ", extraParam.Key, extraParam.Value)
Next
End If
If document.Cookies IsNot Nothing Then
For Each cookie In document.Cookies
paramsBuilder.AppendFormat("--cookie {0} {1} ", cookie.Key, cookie.Value)
Next
End If
paramsBuilder.AppendFormat("""{0}"" ""{1}""", document.Url, outputPdfFilePath)
Try
Dim output As New StringBuilder()
Dim [error] As New StringBuilder()
Using process As New Process()
process.StartInfo.FileName = environment.WkHtmlToPdfPath
process.StartInfo.Arguments = paramsBuilder.ToString()
process.StartInfo.UseShellExecute = False
process.StartInfo.RedirectStandardOutput = True
process.StartInfo.RedirectStandardError = True
process.StartInfo.RedirectStandardInput = True
Using outputWaitHandle As New AutoResetEvent(False)
Using errorWaitHandle As New AutoResetEvent(False)
Dim outputHandler As DataReceivedEventHandler = Function(sender, e)
If e.Data Is Nothing Then
outputWaitHandle.[Set]()
Else
output.AppendLine(e.Data)
End If
End Function
Dim errorHandler As DataReceivedEventHandler = Function(sender, e)
If e.Data Is Nothing Then
errorWaitHandle.[Set]()
Else
[error].AppendLine(e.Data)
End If
End Function
AddHandler process.OutputDataReceived, outputHandler
AddHandler process.ErrorDataReceived, errorHandler
Try
process.Start()
process.BeginOutputReadLine()
process.BeginErrorReadLine()
If document.Html IsNot Nothing Then
Using stream = process.StandardInput
Dim buffer As Byte() = Encoding.UTF8.GetBytes(document.Html)
stream.BaseStream.Write(buffer, 0, buffer.Length)
stream.WriteLine()
End Using
End If
If process.WaitForExit(environment.Timeout) AndAlso outputWaitHandle.WaitOne(environment.Timeout) AndAlso errorWaitHandle.WaitOne(environment.Timeout) Then
If process.ExitCode <> 0 AndAlso Not File.Exists(outputPdfFilePath) Then
Throw New PdfConvertException(String.Format("Html to PDF conversion of '{0}' failed. Wkhtmltopdf output: " & vbCr & vbLf & "{1}", document.Url, [error]))
End If
Else
If Not process.HasExited Then
process.Kill()
End If
Throw New PdfConvertTimeoutException()
End If
Finally
RemoveHandler process.OutputDataReceived, outputHandler
RemoveHandler process.ErrorDataReceived, errorHandler
End Try
End Using
End Using
End Using
If woutput.OutputStream IsNot Nothing Then
Using fs As Stream = New FileStream(outputPdfFilePath, FileMode.Open)
Dim buffer As Byte() = New Byte(32 * 1024 - 1) {}
Dim read As Integer
While (InlineAssignHelper(read, fs.Read(buffer, 0, buffer.Length))) > 0
woutput.OutputStream.Write(buffer, 0, read)
End While
End Using
End If
If woutput.OutputCallback IsNot Nothing Then
Dim pdfFileBytes As Byte() = File.ReadAllBytes(outputPdfFilePath)
woutput.OutputCallback()(document, pdfFileBytes)
End If
Finally
If delete AndAlso File.Exists(outputPdfFilePath) Then
File.Delete(outputPdfFilePath)
End If
End Try
End Sub
Friend Shared Sub ConvertHtmlToPdf(url As String, outputFilePath As String)
ConvertHtmlToPdf(New PdfDocument() With {
.Url = url
}, New PdfOutput() With {
.OutputFilePath = outputFilePath
})
End Sub
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
target = value
Return value
End Function
End Class
End Namespace