DynamicTable.cs
//
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Text;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Html;
namespace DsPdfWeb.Demos
{
// このサンプルでは、1ページに収まらない可能性があるさまざまな行数の
// HTML テーブルを、ページ上の任意の位置から始まるPDFドキュメントに
// 挿入する方法を示します(ただし、すべてのデータ行は同じ高さでなけ
// ればなりません)。
// 最初に単一のデータ行を持つテーブルを作成し、その高さを測定します。
// 次に、2つのデータ行を持つ同様のテーブルを作成し、それも測定します。
// これにより、ヘッダーとデータ行の高さを確認し、テーブルをページ上の
// 目的の位置から PDF にレンダリングし、必要に応じて追加のページに
// 分割できます。
//
// DsHtml をプロジェクトに追加する方法の詳細については、
// HelloWorldHtml サンプルコードの上部にあるコメントのメモを
// 参照してください。
public class DynamicTable
{
public int CreatePDF(Stream stream)
{
// このタグは、CSS スタイルなどを定義するHTMLページテンプレートに
// 準備済みテーブル HTML コードを挿入するために使用されます。
// (このタグを使用すると、表の HTML コードを作成するときに
// string.Format を使用できます。そうしないと、スタイル定義内の
// 中括弧が書式指定子に干渉するためです。)
const string TTAG = "___TABLE___";
// HTML ページテンプレート。
const string tableTpl =
"<!DOCTYPE html>" +
"<html>" +
"<head>" +
"<style>" +
"#employees {" +
" font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif;" +
" border-collapse: collapse;" +
" width: 100%;" +
"}" +
"#employees td, #employees th {" +
" border: 1px solid #ddd;" +
" padding: 8px;" +
"}" +
"#employees tr:nth-child(even){background-color: #f2f2f2;}" +
"#employees tr:hover {background-color: #ddd;}" +
"#employees th {" +
" padding-top: 12px;" +
" padding-bottom: 12px;" +
" text-align: left;" +
" background-color: #3377ff;" +
" color: white;" +
"}" +
"</style>" +
"</head>" +
"<body>" +
TTAG +
"</body>" +
"</html>";
// テーブルの HTML コード書式。
const string tableFmt =
"<table id='employees'>" +
" <tr>" +
" <th>Index</th>" +
" <th>Lorem</th>" +
" <th>Ipsum</th>" +
" </tr>" +
"{0}" +
"</table>";
// テーブル行の HTML コード書式。
const string dataRowFmt =
" <tr>" +
" <td>{0}</td>" +
" <td>{1}</td>" +
" <td>{2}</td>" +
" </tr>";
// 新規 PDF ドキュメントを作成します。
var doc = new GcPdfDocument();
// ページを追加します。
var page = doc.NewPage();
// ページを追加し、そのグラフィックを取得します。
var g = page.Graphics;
// HTML から PDF へのフォーマットオプションを設定します。
// 最も重要なのはサイズの制限です。この場合、プログラムで調整
// するため、高さは制限しません。
// HtmlToPdfFormat では、サイズはインチで指定されることに注意してください。
var hf = new HtmlToPdfFormat(false) { MaxPageWidth = page.Size.Width / 72 };
// 単一のデータ行の HTML コード(サンプルデータ付き)。
var dataRow = string.Format(dataRowFmt, "a", "b", "c");
// 単一のデータ行を持つテーブルを含む HTML ページ。
var thtml = tableTpl.Replace(TTAG, string.Format(tableFmt, dataRow));
// HTML のレンダリングに使用する GcHtmlBrowser のインスタンスを生成します。
using var browser = Common.Util.NewHtmlBrowser();
// 現在の GcPdfGraphics の HTML を測定します。
var s1 = g.MeasureHtml(browser, thtml, hf);
// 同じ HTML ページですが、2つのデータ行があります。
thtml = tableTpl.Replace(TTAG, string.Format(tableFmt, dataRow + dataRow));
// 新しい HTML を測定します。
var s2 = g.MeasureHtml(browser, thtml, hf);
// データ行とヘッダー行の高さを計算します。
var rowHeight = s2.Height - s1.Height;
var headerHeight = s1.Height - rowHeight;
// 最初のページの上部にメモを追加します。
var nrc = Common.Util.AddNote(
"ここでは、最初のページの指定された位置から始まり、複数のページにまたがる" +
"可能性のある未知の行数で HTML テーブルをレンダリングします。",
page);
// ランダムデータでテーブルを構築するための設定。
var lorems = Common.Util.LoremWords();
var rnd = Common.Util.NewRandom();
var sb = new StringBuilder();
// ページレイアウトパラメータ。
var marginx = nrc.Left;
var marginy = nrc.Top;
var x = marginx;
var y = nrc.Bottom + 36;
var tbottom = nrc.Bottom + 36 + headerHeight;
// レンダリングするランダムな数のデータ行。
int nrows = rnd.Next(100, 200);
// テーブルを生成してレンダリングし、必要に応じて継続ページを追加します。
for (int i = 0; i < nrows; ++i)
{
sb.AppendFormat(dataRowFmt, i, lorems[rnd.Next(lorems.Count)], lorems[rnd.Next(lorems.Count)]);
tbottom += rowHeight;
var lastPage = i == nrows - 1;
if (tbottom >= page.Size.Height - 72 || lastPage)
{
var html = tableTpl.Replace(TTAG, string.Format(tableFmt, sb.ToString()));
var ok = g.DrawHtml(browser, html, x, y,
new HtmlToPdfFormat(false) { MaxPageWidth = (page.Size.Width - marginx * 2) / 72 },
out SizeF size);
if (!lastPage)
{
page = doc.NewPage();
g = page.Graphics;
y = 72;
tbottom = y + headerHeight;
sb.Clear();
}
}
}
// PDF ドキュメントを保存します。
doc.Save(stream);
return doc.Pages.Count;
}
}
}