'' 完毕:
Imports System.IO
Imports System.Drawing
Imports System.Text
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
'' 此示例演示了不同样式的编号列表如何
'' 可以在 GcDocs.Pdf 中呈现。
'' 另请参阅NumberedList。
Public Class NumberedList2
'' 封装示例中使用的页面布局常量:
Private Structure Layout
'' 四周页边距:
Public Shared Margin As Single = 72.0F
'' 相对于项目编号的列表偏移量:
Public Shared ListOffset As Single = 24.0F
'' 列表级缩进:
Public Shared ListIndent As Single = 30.0F
End Structure
'' 定义简单树类型:
Private Class Node
Public Sub New(ByVal txt As String)
Text = txt
End Sub
Public Property Text As String
Public Property Children As List(Of Node) = New List(Of Node)()
End Class
'' 将节点列表呈现为编号列表。
Private Function RenderNodes(ByRef page As Page, ByVal pt As PointF, ByVal nodes As List(Of Node), ByVal level As Integer) As PointF
Dim tlBullet = page.Graphics.CreateTextLayout()
tlBullet.DefaultFormat.Font = StandardFonts.Times
tlBullet.MarginLeft = Layout.ListIndent * level
Dim tlText = New TextLayout(72)
tlText.DefaultFormat.Font = StandardFonts.Times
tlText.MarginLeft = Layout.ListOffset + Layout.ListIndent * level
For i = 0 To nodes.Count - 1
Dim g = page.Graphics
'' 准备项目文本:
tlText.Clear()
tlText.Append(nodes(i).Text)
tlText.PerformLayout(True)
If pt.Y + tlText.ContentHeight > page.Size.Height - Layout.Margin Then
page = page.Doc.NewPage()
g = page.Graphics
pt.Y = Layout.Margin
End If
'' 准备品编号:
tlBullet.Clear()
tlBullet.Append(ItemIdxToString(i, level, tlBullet))
tlBullet.PerformLayout(True)
'' 渲染项目:
g.DrawTextLayout(tlBullet, pt)
g.DrawTextLayout(tlText, pt)
'' 提前插入点:
pt.Y += tlText.ContentHeight
'' 渲染子项:
If nodes(i).Children.Count > 0 Then
pt = RenderNodes(page, pt, nodes(i).Children, level + 1)
End If
Next
Return pt
End Function
'' 将项目索引转换为项目编号表示形式
'' 阿拉伯语 -> 拉丁字母 -> 罗马数字循环。
'' 罗马数字右对齐,其他数字左对齐。
Private Function ItemIdxToString(ByVal itemIdx As Integer, ByVal level As Integer, ByVal tl As TextLayout) As String
Select Case (level Mod 3)
Case 0
tl.MarginLeft = Layout.ListIndent * level
tl.MaxWidth = Nothing
tl.TextAlignment = TextAlignment.Leading
Return $"{itemIdx + 1}."
Case 1
tl.MarginLeft = Layout.ListIndent * level
tl.MaxWidth = Nothing
tl.TextAlignment = TextAlignment.Leading
Return $"{ChrW(AscW("a") + itemIdx)}."
Case 2
tl.MarginLeft = 0
Dim font = tl.DefaultFormat.Font
tl.MaxWidth = Layout.ListIndent * level + tl.DefaultFormat.FontSize
tl.TextAlignment = TextAlignment.Trailing
Return $"{IntToRoman(itemIdx + 1)}."
Case Else
Throw New Exception("Unexpected.")
End Select
End Function
'' 来自http://dotnet-snippets.com/snippet/roman-numerals/667
Private Function IntToRoman(ByVal number As Integer) As String
Dim result = New StringBuilder()
Dim digitsValues = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000}
Dim romanDigits = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"}
While number > 0
For i = digitsValues.Count() - 1 To 0 Step -1
If (number / digitsValues(i) >= 1) Then
number -= digitsValues(i)
result.Append(romanDigits(i).ToLower())
Exit For
End If
Next
End While
Return result.ToString()
End Function
'' 主要入口点:
Function CreatePDF(ByVal stream As Stream) As Integer
Dim doc = New GcPdfDocument()
Dim page = doc.NewPage()
RenderNodes(page, New PointF(Layout.Margin, Layout.Margin), _arthrapods.Children, 0)
''
'' 完毕:
doc.Save(stream)
Return doc.Pages.Count
End Function
'' 示例树数据:
Private _arthrapods As New Node("Animalia Arthrapoda") With
{
.Children = New List(Of Node) From
{
New Node("Insecta") With
{
.Children = New List(Of Node) From
{
New Node("Archaeognatha") With
{
.Children = New List(Of Node) From
{
New Node("Protozoa")
}
},
New Node("Thysanura") With
{
.Children = New List(Of Node) From
{
New Node("Silverfish")
}
},
New Node("Ephemeoptera") With
{
.Children = New List(Of Node) From
{
New Node("Mafly")
}
},
New Node("Odonata") With
{
.Children = New List(Of Node) From
{
New Node("Dragonfly"),
New Node("Azure Damzelfly"),
New Node("Emerald Damzelfly")
}
},
New Node("Orthoptera") With
{
.Children = New List(Of Node) From
{
New Node("Grasshopper"),
New Node("Cricket"),
New Node("Cave Cricket")
}
},
New Node("Phasmatodea") With
{
.Children = New List(Of Node) From
{
New Node("Walking Stick"),
New Node("Leaf Bug")
}
},
New Node("Mantodea") With
{
.Children = New List(Of Node) From
{
New Node("Praying Mantis")
}
},
New Node("Blattoeda") With
{
.Children = New List(Of Node) From
{
New Node("Cockroach")
}
},
New Node("Isoptera") With
{
.Children = New List(Of Node) From
{
New Node("Termite")
}
},
New Node("Phithiraptera") With
{
.Children = New List(Of Node) From
{
New Node("Bird Lice"),
New Node("Human Lice"),
New Node("Pubic Lice")
}
},
New Node("Hemiptera") With
{
.Children = New List(Of Node) From
{
New Node("Cicada"),
New Node("Pond Skater"),
New Node("Tree Hopper"),
New Node("Stink Bug"),
New Node("Thrip"),
New Node("Alderfly")
}
},
New Node("Siphonatera") With
{
.Children = New List(Of Node) From
{
New Node("Flea")
}
}
}
},
New Node("Myriapoda") With
{
.Children = New List(Of Node) From
{
New Node("Chilopoda") With
{
.Children = New List(Of Node) From
{
New Node("Centipede")
}
},
New Node("Diplopoda") With
{
.Children = New List(Of Node) From
{
New Node("Millipede"),
New Node("Pitbug")
}
}
}
},
New Node("Crustacea") With
{
.Children = New List(Of Node) From
{
New Node("Branchiopod") With
{
.Children = New List(Of Node) From
{
New Node("Brine Shrimp"),
New Node("Water Flea")
}
},
New Node("Maxillopod") With
{
.Children = New List(Of Node) From
{
New Node("Cyclopoid"),
New Node("Calgid"),
New Node("Barnacles")
}
},
New Node("Malacostracan") With
{
.Children = New List(Of Node) From
{
New Node("Krill"),
New Node("Prawn"),
New Node("Shrimp"),
New Node("Cancrid Crab"),
New Node("Fidder Crab"),
New Node("Spider Crab"),
New Node("Lobster"),
New Node("Hermit Crab"),
New Node("Cray Fish")
}
}
}
},
New Node("Pycnogonida") With
{
.Children = New List(Of Node) From
{
New Node("Pycnogonida") With
{
.Children = New List(Of Node) From
{
New Node("Sea Spider")
}
}
}
},
New Node("Merostomata") With
{
.Children = New List(Of Node) From
{
New Node("Merostomata") With
{
.Children = New List(Of Node) From
{
New Node("Horseshoe Spider")
}
}
}
},
New Node("Arachnida") With
{
.Children = New List(Of Node) From
{
New Node("Scorpiones") With
{
.Children = New List(Of Node) From
{
New Node("Buthid"),
New Node("Imperial Scorpion")
}
},
New Node("Pseudoscorpions") With
{
.Children = New List(Of Node) From
{
New Node("Neobisiid"),
New Node("Cheliferid")
}
},
New Node("Solfigugae") With
{
.Children = New List(Of Node) From
{
New Node("Wind Scorpion")
}
},
New Node("Acari") With
{
.Children = New List(Of Node) From
{
New Node("Tick"),
New Node("Mite")
}
},
New Node("Araneae") With
{
.Children = New List(Of Node) From
{
New Node("Crib Weaver"),
New Node("Funnel-web Spider"),
New Node("Funnel Weaver"),
New Node("Water Spider"),
New Node("Jumping Spider"),
New Node("Wolf Spider"),
New Node("Nursery-web Spider"),
New Node("Crab Spider"),
New Node("Black Widow"),
New Node("Tiger Oriental Tarantula"),
New Node("Mexican Red-legged Tarantula")
}
}
}
}
}
}
End Class