'' 完毕:
Imports System.IO
Imports System.Drawing
Imports System.Linq
Imports System.Reflection
Imports System.Collections.Generic
Imports System.Globalization
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports s2industries.ZUGFeRD
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing
'' 此示例演示如何从 ZUGFeRD 兼容的 XML 附件中检索发票数据。
'' 所有 ZUGFeRD 数据都会打印到此示例生成的 PDF 中。
'' See ZugferdInfo 以获取类似的示例,该示例打印 ZUGFeRD 数据的选定部分。
'' 包含 ZUGFeRD 数据的示例 PDF 发票,该示例将其用作输入
'' 由ZugferdInvoice生成。
''
'' ZUGFeRD 是基于 PDF 和 XML 文件格式的德国电子发票标准。
'' 它准备改变发票的处理方式,并可供任何类型的企业使用。
'' 它将使发件人和客户的发票处理更加高效。
'' 详细信息请参见什么是ZUGFeRD? 。
''
'' 此示例使用 ZUGFeRD-csharp 包
'' 解析附加到发票的 ZUGFeRD 兼容 XML。
Public Class ZugferdInfoExt
Function CreatePDF(ByVal stream As Stream) As Integer
'' The sample invoice with ZUGFeRD data:
Dim invoicePdf = Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf")
'' Output document:
Dim doc = New GcPdfDocument()
Using fs = File.OpenRead(invoicePdf)
'' Load the ZUGFeRD compliant invoice PDF:
Dim invoice = New GcPdfDocument()
invoice.Load(fs)
'' Get the ZUGFeRD attachment from the invoice by the ZUGFeRD 1.x standard file name:
Dim attachment = invoice.EmbeddedFiles.Values.FirstOrDefault(Function(it) it.File.FileName = "ZUGFeRD-invoice.xml")
If attachment IsNot Nothing Then
Using xmlstream = attachment.GetStream()
'' Load the invoice descriptor:
Dim descriptor = InvoiceDescriptor.Load(xmlstream)
Dim tl = New TextLayout(72)
tl.MaxWidth = doc.PageSize.Width
tl.MaxHeight = doc.PageSize.Height
tl.MarginAll = tl.Resolution
tl.DefaultTabStops = 24
'' Recursively render all InvoiceDescriptor properties to text layout:
tl.AppendLine($"{NameOf(InvoiceDescriptor)}:", _tfStrong)
RenderProperties(descriptor, tl, 1)
'' Write text layout to output PDF
tl.PerformLayout(True)
Dim topt = New TextSplitOptions(tl)
While (True)
Dim rest As TextLayout = Nothing
Dim splitResult = tl.Split(topt, rest)
doc.Pages.Add().Graphics.DrawTextLayout(tl, PointF.Empty)
If splitResult <> SplitResult.Split Then
Exit While
End If
tl = rest
End While
'' Done:
doc.Save(stream)
Return doc.Pages.Count
End Using
Else
Return 0
End If
End Using
End Function
'' Recursively print all source's properties to text layout:
Shared Sub RenderProperties(ByVal source As Object, ByVal tl As TextLayout, ByVal level As Integer)
If source Is Nothing Then
Return
End If
Dim props = source.GetType().GetProperties()
For Each prop In props
RenderProperty(prop, source, tl, level)
Next
End Sub
'' Text formats for output:
Private Shared ReadOnly _tfData = New TextFormat() With {
.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf")),
.FontSize = 12
}
Private Shared ReadOnly _tfStrong = New TextFormat(_tfData) With {
.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeuib.ttf"))
}
Private Shared ReadOnly _tfLabels = New TextFormat(_tfData) With {
.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeuii.ttf")),
.FontSize = 11
}
'' Print a property:
Shared Sub RenderProperty(ByVal prop As PropertyInfo, ByVal parent As Object, ByVal tl As TextLayout, ByVal level As Integer)
Dim space = String.Empty
For i = 0 To level - 1
space += vbTab
Next
Dim name = prop.Name
Dim value = prop.GetValue(parent, Nothing)
If value Is Nothing Then
tl.Append(space, _tfLabels)
tl.AppendLine($"{name}:", _tfLabels)
ElseIf (value.GetType().IsValueType OrElse value.GetType() Is GetType(String)) Then
tl.Append(space, _tfLabels)
tl.Append($"{name}: ", _tfLabels)
tl.AppendLine(String.Format(CultureInfo.GetCultureInfo("en-US"), "{0}", value), _tfData)
Else
If TypeOf value Is IEnumerable(Of Object) Then
Dim collection As IEnumerable(Of Object) = CType(value, IEnumerable(Of Object))
Dim index = 0
For Each item In collection
tl.Append(space, _tfLabels)
tl.AppendLine($"Collection item {name} [{index}]:", _tfStrong)
index += 1
RenderProperties(item, tl, level + 1)
Next
Else
tl.Append(space, _tfLabels)
tl.AppendLine($"Container {name}:", _tfStrong)
RenderProperties(value, tl, level + 1)
End If
End If
End Sub
End Class