ZugferdInfoExt.vb
  1. ''
  2. '' This code is part of Document Solutions for PDF demos.
  3. '' Copyright (c) MESCIUS inc. All rights reserved.
  4. ''
  5. Imports System.IO
  6. Imports System.Drawing
  7. Imports System.Linq
  8. Imports System.Reflection
  9. Imports System.Collections.Generic
  10. Imports System.Globalization
  11. Imports GrapeCity.Documents.Pdf
  12. Imports GrapeCity.Documents.Text
  13. Imports s2industries.ZUGFeRD
  14. Imports GCTEXT = GrapeCity.Documents.Text
  15. Imports GCDRAW = GrapeCity.Documents.Drawing
  16.  
  17. '' This sample demonstrates how to retrieve invoice data from a ZUGFeRD compliant XML attachment.
  18. '' All ZUGFeRD data is printed to the PDF generated by this sample.
  19. '' See ZugferdInfo for a similar sample that prints selected portions of the ZUGFeRD data.
  20.  
  21. '' The sample PDF invoice containing ZUGFeRD data which this sample uses as input
  22. '' was generated by ZugferdInvoice.
  23. ''
  24. '' ZUGFeRD is a German e-invoicing standard based around PDF and XML file formats.
  25. '' Its poised to change the way invoices are handled and can be used by any sort of business.
  26. '' It will make invoice processing more efficient for senders and customers.
  27. '' For details please see What is ZUGFeRD?.
  28. ''
  29. '' This sample uses the ZUGFeRD-csharp package
  30. '' to parse the ZUGFeRD-compatible XML that is attached to the invoice.
  31. Public Class ZugferdInfoExt
  32. Function CreatePDF(ByVal stream As Stream) As Integer
  33. '' The sample invoice with ZUGFeRD data:
  34. Dim invoicePdf = Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf")
  35.  
  36. '' Output document:
  37. Dim doc = New GcPdfDocument()
  38. Using fs = File.OpenRead(invoicePdf)
  39. '' Load the ZUGFeRD compliant invoice PDF:
  40. Dim invoice = New GcPdfDocument()
  41. invoice.Load(fs)
  42.  
  43. '' Get the ZUGFeRD attachment from the invoice by the ZUGFeRD 1.x standard file name:
  44. Dim attachment = invoice.EmbeddedFiles.Values.FirstOrDefault(Function(it) it.File.FileName = "ZUGFeRD-invoice.xml")
  45. If attachment IsNot Nothing Then
  46. Using xmlstream = attachment.GetStream()
  47. '' Load the invoice descriptor:
  48. Dim descriptor = InvoiceDescriptor.Load(xmlstream)
  49.  
  50. Dim tl = New TextLayout(72)
  51. tl.MaxWidth = doc.PageSize.Width
  52. tl.MaxHeight = doc.PageSize.Height
  53. tl.MarginAll = tl.Resolution
  54. tl.DefaultTabStops = 24
  55.  
  56. '' Recursively render all InvoiceDescriptor properties to text layout:
  57. tl.AppendLine($"{NameOf(InvoiceDescriptor)}:", _tfStrong)
  58. RenderProperties(descriptor, tl, 1)
  59.  
  60. '' Write text layout to output PDF
  61. tl.PerformLayout(True)
  62. Dim topt = New TextSplitOptions(tl)
  63. While (True)
  64. Dim rest As TextLayout = Nothing
  65. Dim splitResult = tl.Split(topt, rest)
  66. doc.Pages.Add().Graphics.DrawTextLayout(tl, PointF.Empty)
  67. If splitResult <> SplitResult.Split Then
  68. Exit While
  69. End If
  70. tl = rest
  71. End While
  72. '' Done:
  73. doc.Save(stream)
  74. Return doc.Pages.Count
  75. End Using
  76. Else
  77. Return 0
  78. End If
  79. End Using
  80. End Function
  81.  
  82. '' Recursively print all source's properties to text layout:
  83. Shared Sub RenderProperties(ByVal source As Object, ByVal tl As TextLayout, ByVal level As Integer)
  84. If source Is Nothing Then
  85. Return
  86. End If
  87. Dim props = source.GetType().GetProperties()
  88. For Each prop In props
  89. RenderProperty(prop, source, tl, level)
  90. Next
  91. End Sub
  92.  
  93. '' Text formats for output:
  94. Private Shared ReadOnly _tfData = New TextFormat() With {
  95. .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf")),
  96. .FontSize = 12
  97. }
  98. Private Shared ReadOnly _tfStrong = New TextFormat(_tfData) With {
  99. .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeuib.ttf"))
  100. }
  101. Private Shared ReadOnly _tfLabels = New TextFormat(_tfData) With {
  102. .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeuii.ttf")),
  103. .FontSize = 11
  104. }
  105.  
  106. '' Print a property:
  107. Shared Sub RenderProperty(ByVal prop As PropertyInfo, ByVal parent As Object, ByVal tl As TextLayout, ByVal level As Integer)
  108. Dim space = String.Empty
  109. For i = 0 To level - 1
  110. space += vbTab
  111. Next
  112. Dim name = prop.Name
  113. Dim value = prop.GetValue(parent, Nothing)
  114. If value Is Nothing Then
  115. tl.Append(space, _tfLabels)
  116. tl.AppendLine($"{name}:", _tfLabels)
  117. ElseIf (value.GetType().IsValueType OrElse value.GetType() Is GetType(String)) Then
  118. tl.Append(space, _tfLabels)
  119. tl.Append($"{name}: ", _tfLabels)
  120. tl.AppendLine(String.Format(CultureInfo.GetCultureInfo("en-US"), "{0}", value), _tfData)
  121. Else
  122. If TypeOf value Is IEnumerable(Of Object) Then
  123. Dim collection As IEnumerable(Of Object) = CType(value, IEnumerable(Of Object))
  124. Dim index = 0
  125. For Each item In collection
  126. tl.Append(space, _tfLabels)
  127. tl.AppendLine($"Collection item {name} [{index}]:", _tfStrong)
  128. index += 1
  129. RenderProperties(item, tl, level + 1)
  130. Next
  131. Else
  132. tl.Append(space, _tfLabels)
  133. tl.AppendLine($"Container {name}:", _tfStrong)
  134. RenderProperties(value, tl, level + 1)
  135. End If
  136. End If
  137. End Sub
  138. End Class
  139.