// 完毕:
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Drawing;
namespace DsPdfWeb.Demos.Basics
{
// 此示例演示了不同样式的编号列表如何
// 可以在 GcDocs.Pdf 中呈现。
// 另请参阅NumberedList。
public class NumberedList2
{
// 封装示例中使用的页面布局常量:
private struct Layout
{
// 四周页边距:
public static float Margin => 72;
// 相对于项目编号的列表偏移量:
public static float ListOffset => 24;
// 列表级缩进:
public static float ListIndent => 30;
};
// 定义简单树类型:
private class Node
{
public Node(string text)
{
Text = text;
}
public string Text { get; }
public List<Node> Children = new List<Node>();
}
// 将节点列表呈现为编号列表。
private PointF RenderNodes(ref Page page, PointF pt, List<Node> nodes, int level)
{
var tlBullet = new TextLayout(72);
tlBullet.DefaultFormat.Font = StandardFonts.Times;
tlBullet.MarginLeft = Layout.ListIndent * level;
var tlText = new TextLayout(72);
tlText.DefaultFormat.Font = StandardFonts.Times;
tlText.MarginLeft = Layout.ListOffset + Layout.ListIndent * level;
for (int i = 0; i < nodes.Count; ++i)
{
var g = page.Graphics;
// 准备项目文本:
tlText.Clear();
tlText.Append(nodes[i].Text);
tlText.PerformLayout(true);
if (pt.Y + tlText.ContentHeight > page.Size.Height - Layout.Margin)
{
page = page.Doc.NewPage();
g = page.Graphics;
pt.Y = Layout.Margin;
}
// 准备品编号:
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)
pt = RenderNodes(ref page, pt, nodes[i].Children, level + 1);
}
return pt;
}
// 将项目索引转换为项目编号表示形式
// 阿拉伯语 -> 拉丁字母 -> 罗马数字循环。
// 罗马数字右对齐,其他数字左对齐。
private string ItemIdxToString(int itemIdx, int level, TextLayout tl)
{
switch (level % 3)
{
case 0:
tl.MarginLeft = Layout.ListIndent * level;
tl.MaxWidth = null;
tl.TextAlignment = TextAlignment.Leading;
return $"{itemIdx + 1}.";
case 1:
tl.MarginLeft = Layout.ListIndent * level;
tl.MaxWidth = null;
tl.TextAlignment = TextAlignment.Leading;
return $"{(char)('a' + itemIdx)}.";
case 2:
tl.MarginLeft = 0;
var font = tl.DefaultFormat.Font;
tl.MaxWidth = Layout.ListIndent * level + tl.DefaultFormat.FontSize;
tl.TextAlignment = TextAlignment.Trailing;
return $"{IntToRoman(itemIdx + 1)}.";
default:
throw new Exception("Unexpected.");
}
}
// 来自http://dotnet-snippets.com/snippet/roman-numerals/667
private string IntToRoman(int number)
{
var result = new StringBuilder();
int[] digitsValues = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
string[] romanDigits = { "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M" };
while (number > 0)
{
for (int i = digitsValues.Count() - 1; i >= 0; i--)
if (number / digitsValues[i] >= 1)
{
number -= digitsValues[i];
result.Append(romanDigits[i].ToLower());
break;
}
}
return result.ToString();
}
// 主要入口点:
public int CreatePDF(Stream stream)
{
var doc = new GcPdfDocument();
var page = doc.NewPage();
RenderNodes(ref page, new PointF(Layout.Margin, Layout.Margin), _arthrapods.Children, 0);
// 完毕:
doc.Save(stream);
return doc.Pages.Count;
}
// 示例树数据:
private Node _arthrapods = new Node("Animalia Arthrapoda")
{
Children = new List<Node>()
{
new Node("Insecta")
{
Children = new List<Node>()
{
new Node("Archaeognatha")
{
Children = new List<Node>()
{
new Node("Protozoa")
},
},
new Node("Thysanura")
{
Children = new List<Node>()
{
new Node("Silverfish")
},
},
new Node("Ephemeoptera")
{
Children = new List<Node>()
{
new Node("Mafly")
},
},
new Node("Odonata")
{
Children = new List<Node>()
{
new Node("Dragonfly"),
new Node("Azure Damzelfly"),
new Node("Emerald Damzelfly"),
},
},
new Node("Orthoptera")
{
Children = new List<Node>()
{
new Node("Grasshopper"),
new Node("Cricket"),
new Node("Cave Cricket"),
},
},
new Node("Phasmatodea")
{
Children = new List<Node>()
{
new Node("Walking Stick"),
new Node("Leaf Bug"),
},
},
new Node("Mantodea")
{
Children = new List<Node>()
{
new Node("Praying Mantis"),
},
},
new Node("Blattoeda")
{
Children = new List<Node>()
{
new Node("Cockroach"),
},
},
new Node("Isoptera")
{
Children = new List<Node>()
{
new Node("Termite"),
},
},
new Node("Phithiraptera")
{
Children = new List<Node>()
{
new Node("Bird Lice"),
new Node("Human Lice"),
new Node("Pubic Lice"),
},
},
new Node("Hemiptera")
{
Children = new List<Node>()
{
new Node("Cicada"),
new Node("Pond Skater"),
new Node("Tree Hopper"),
new Node("Stink Bug"),
new Node("Thrip"),
new Node("Alderfly"),
},
},
new Node("Siphonatera")
{
Children = new List<Node>()
{
new Node("Flea"),
},
},
// Coleoptera etc skipped
},
},
new Node("Myriapoda")
{
Children = new List<Node>()
{
new Node("Chilopoda")
{
Children = new List<Node>()
{
new Node("Centipede"),
},
},
new Node("Diplopoda")
{
Children = new List<Node>()
{
new Node("Millipede"),
new Node("Pitbug"),
},
},
},
},
new Node("Crustacea")
{
Children = new List<Node>()
{
new Node("Branchiopod")
{
Children = new List<Node>()
{
new Node("Brine Shrimp"),
new Node("Water Flea"),
},
},
new Node("Maxillopod")
{
Children = new List<Node>()
{
new Node("Cyclopoid"),
new Node("Calgid"),
new Node("Barnacles"),
},
},
new Node("Malacostracan")
{
Children = new List<Node>()
{
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")
{
Children = new List<Node>()
{
new Node("Pycnogonida")
{
Children = new List<Node>()
{
new Node("Sea Spider"),
},
},
},
},
new Node("Merostomata")
{
Children = new List<Node>()
{
new Node("Merostomata")
{
Children = new List<Node>()
{
new Node("Horseshoe Spider"),
},
},
},
},
new Node("Arachnida")
{
Children = new List<Node>()
{
new Node("Scorpiones")
{
Children = new List<Node>()
{
new Node("Buthid"),
new Node("Imperial Scorpion"),
},
},
new Node("Pseudoscorpions")
{
Children = new List<Node>()
{
new Node("Neobisiid"),
new Node("Cheliferid"),
},
},
new Node("Solfigugae")
{
Children = new List<Node>()
{
new Node("Wind Scorpion"),
},
},
new Node("Acari")
{
Children = new List<Node>()
{
new Node("Tick"),
new Node("Mite"),
},
},
new Node("Araneae")
{
Children = new List<Node>()
{
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"),
},
},
},
},
},
};
}
}