ProductList.vb
'' 
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' © MESCIUS inc. All rights reserved.
'' 
Imports System.IO
Imports System.Drawing
Imports System.Text
Imports System.Data
Imports System.Linq
Imports System.Collections.Generic
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Html

'' このサンプルは、テンプレートとして HTML 文字列を使用したレポート
'' (標準の NWind サンプルデータベースの商品リスト)をレンダリングする方法を
'' 示します。 レポートは、データレコードをループし、実際のデータで満たされたテーブル行
'' テンプレートから結果の HTML を作成することにより作成されます。 生成された
'' HTML 文字列は SaveAsPdf メソッドにて PDF にレンダリングされます。
'' 
'' DsHtml をプロジェクトに追加する方法の詳細については、HelloWorldHtml
'' サンプルコードの上部にあるコメントのメモを参照してください。
Public Class ProductList
    Sub CreatePDF(ByVal stream As Stream)
        Const TTAG = "___TABLE___"

        '' HTML ページテンプレート。
        Const tableTpl =
            "<!DOCTYPE html>" +
            "<html>" +
            "<head>" +
            "<style>" +
            "" +
            "html * {" +
            "  font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif !important;" +
            "}" +
            "" +
            "h1 {" +
            "  color: #1a5276;" +
            "  background-color: #d2b4de;" +
            "  text-align: center;" +
            "  padding: 6px;" +
            "}" +
            "" +
            "thead {display: table-header-group;}" +
            "" +
            "#products {" +
            "  font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif;" +
            "  border-collapse: collapse;" +
            "  width: 100%;" +
            "}" +
            "" +
            "#products td, #products th {" +
            "  border: 1px solid #ddd;" +
            "  padding: 8px;" +
            "}" +
            "" +
            "#products tr:nth-child(even){background-color: #f2f2f2;}" +
            "" +
            "#products tr:hover {background-color: #ddd;}" +
            "" +
            "#products th {" +
            "  padding-top: 12px;" +
            "  padding-bottom: 12px;" +
            "  text-align: left;" +
            "  background-color: #a569bd;" +
            "  color: white;" +
            "}" +
            "</style>" +
            "</head>" +
            "<body>" +
            "" +
            TTAG +
            "" +
            "</body>" +
            "</html>"

        Const tableHead = "<h1>商品価格リスト</h1>"

        Const tableFmt =
            "<table id='products'>" +
            "  <thead>" +
            "    <th>商品 ID</th>" +
            "    <th>商品名</th>" +
            "    <th>仕入先</th>" +
            "    <th>単位・入数</th>" +
            "    <th>単価</th>" +
            "  </thead>" +
            "{0}" +
            "</table>"

        Const dataRowFmt =
            "  <tr>" +
            "    <td>{0}</td>" +
            "    <td>{1}</td>" +
            "    <td>{2}</td>" +
            "    <td>{3}</td>" +
            "    <td align='right'>{4:C}</td>" +
            "  </tr>"

        Using ds = New DataSet()
            ds.ReadXml(Path.Combine("Resources", "data", "GcNWind.xml"))

            Dim dtProds = ds.Tables("Products")
            Dim dtSupps = ds.Tables("Suppliers")

            Dim products =
            From prod In dtProds.Select()
            Join supp In dtSupps.Select()
            On prod("SupplierID") Equals supp("SupplierID")
            Order By prod("ProductName")
            Select New With {
                .ProductID = prod("ProductID"),
                .ProductName = prod("ProductName"),
                .Supplier = supp("CompanyName"),
                .QuantityPerUnit = prod("QuantityPerUnit"),
                .UnitPrice = prod("UnitPrice")
            }

            Dim sb = New StringBuilder()
            sb.AppendLine(tableHead)
            For Each prod In products
                sb.AppendFormat(dataRowFmt, prod.ProductID, prod.ProductName, prod.Supplier, prod.QuantityPerUnit, prod.UnitPrice)
            Next

            Dim html = tableTpl.Replace(TTAG, String.Format(tableFmt, sb.ToString()))
            Dim tmp = Path.GetTempFileName()
            '' HTML のレンダリングに使用する GcHtmlBrowser のインスタンスを生成します。
            Using browser = Util.NewHtmlBrowser()
                '' PdfOptions では、HTML から PDF への変換のオプションを提供できます。
                Dim pdfOptions = New PdfOptions() With {
                    .Margins = New PdfMargins(0.2F, 1, 0.2F, 1),
                    .DisplayHeaderFooter = True,
                    .HeaderTemplate = "<div style='color:#1a5276; font-size:12px; width:1000px; margin-left:0.2in; margin-right:0.2in'>" +
                        "<span style='float:left;'>Product Price List</span>" +
                        "<span style='float:right'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></span>" +
                        "</div>",
                    .FooterTemplate = "<div style='color: #1a5276; font-size:12em; width:1000px; margin-left:0.2in; margin-right:0.2in;'>" +
                        "<span>(c) MESCIUS inc. All Rights Reserved.</span>" +
                        "<span style='float:right'>Generated on <span class='date'></span></span></div>"
                }
                '' ソース Web ページを一時ファイルにレンダリングします。
                Using htmlPage = browser.NewPage(html)
                    htmlPage.SaveAsPdf(tmp, pdfOptions)
                End Using
            End Using
            '' 作成した PDF を一時ファイルからターゲットストリームにコピーします。
            Using ts = File.OpenRead(tmp)
                ts.CopyTo(stream)
            End Using
            '' 一時ファイルを削除します。
            File.Delete(tmp)
        End Using
        '' PDF ドキュメントを保存します。
    End Sub
End Class