GetTableData.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Recognition;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Common;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsPdfWeb.Demos
{
    // テーブルからデータを抽出します。
    public class GetTableData
    {
        public int CreatePDF(Stream stream)
        {
            const float DPI = 72;
            const float margin = 36;
            var doc = new GcPdfDocument();

            var tf = new TextFormat()
            {
                Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "ipag.ttc")),
                FontSize = 9,
                ForeColor = Color.Black
            };
            var tfHdr = new TextFormat(tf)
            {
                FontBold = true,
                FontSize = 11,
                ForeColor = Color.DarkBlue
            };
            var tfRed = new TextFormat(tf) { ForeColor = Color.Red };

            using (var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf")))
            {
                // 大体のテーブルの範囲を指定します。
                var tableBounds = new RectangleF(0, 3 * DPI, 8.5f * DPI, 3.75f * DPI);

                var page = doc.NewPage();
                page.Landscape = true;
                var g = page.Graphics;

                var rc = Common.Util.AddNote(
                    "このサンプルでは、テーブルを含むPDF(請求書のサンプル)を読み込み、" +
                    "Page.GetTable()メソッドを用いてPDFからテーブルを抽出しています。" +
                    "抽出されたデータは、行とセルのリストとして出力されます。" +
                    "テーブルを含む元のPDFも、参照用に生成されるPDFに追加されます。",
                    page,
                    new RectangleF(margin, margin, page.Bounds.Width - margin * 2, page.Bounds.Height - margin * 2));

                var tl = g.CreateTextLayout();
                tl.MaxWidth = page.Bounds.Width;
                tl.MaxHeight = page.Bounds.Height;
                tl.MarginAll = margin;
                tl.MarginTop = rc.Bottom;
                tl.DefaultTabStops = 150;
                tl.LineSpacingScaleFactor = 1.2f;

                var docSrc = new GcPdfDocument();
                docSrc.Load(fs);

                var itable = docSrc.Pages[0].GetTable(tableBounds);

                if (itable == null)
                {
                    tl.AppendLine($"指定された範囲にテーブルは見つかりませんでした。", tfRed);
                }
                else
                {
                    tl.Append($"\nテーブルには、列が {itable.Cols.Count} 列と、行が {itable.Rows.Count} 行あります。データは以下のとおりです。", tfHdr);
                    tl.AppendParagraphBreak();
                    for (int row = 0; row < itable.Rows.Count; ++row)
                    {
                        var tfmt = row == 0 ? tfHdr : tf;
                        for (int col = 0; col < itable.Cols.Count; ++col)
                        {
                            var cell = itable.GetCell(row, col);
                            if (col > 0)
                                tl.Append("\t", tfmt);
                            if (cell == null)
                                tl.Append("<セルなし>", tfRed);
                            else
                                tl.Append(cell.Text, tfmt);
                        }
                        tl.AppendLine();
                    }
                }

                var to = new TextSplitOptions(tl) { RestMarginTop = margin, MinLinesInFirstParagraph = 2, MinLinesInLastParagraph = 2 };
                tl.PerformLayout(true);
                while (true)
                {
                    var splitResult = tl.Split(to, out TextLayout rest);
                    doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty);
                    if (splitResult != SplitResult.Split)
                        break;
                    tl = rest;
                    doc.NewPage().Landscape = true;
                }

                // 参照のため元のドキュメントを追加します。
                doc.MergeWithDocument(docSrc);

                doc.Save(stream);
                return doc.Pages.Count;
            }
        }
    }
}