AiGetTable.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.Text;
using GrapeCity.Documents.Pdf.AI;
using GrapeCity.Documents.Layout;
using GrapeCity.Documents.Drawing;
using DsPdfWeb.Demos.Common;
using System.Threading.Tasks;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsPdfWeb.Demos
{
    // このサンプルは PDF AIアシスタント (DsPdfAI) を使用して、
    // PDF内の指定された表からデータを抽出します。
    // 抽出されたデータは TableRenderer を使用して1ページ目に挿入されます。
    // この方法は PlainTable サンプルで示されているアプローチに従っています。
    //
    // このサンプルをローカルで実行するには、
    // Util.OpenAIToken、Util.AzureOpenAIToken、Util.AzureEndPoint プロパティを使用して
    // OpenAI の認証情報と Azure のエンドポイントを設定してください。

    public class AiGetTable
    {
        public int CreatePDF(Stream stream, int paramsIdx = 0)
        {
            return CreatePDF(stream, GetSampleParamsList()[paramsIdx]);
        }

        public int CreatePDF(Stream stream, string[] sampleParams)
        {
            var doc = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", sampleParams[3]));
            doc.Load(fs);
            try
            {
                var a = new AzureOpenAIDocumentAssistant(Util.AzureEndPoint, Util.AzureOpenAIToken);
                var task = a.GetTable(doc, sampleParams[4]);
                task.Wait();

                var page = doc.Pages.Insert(0);
                var rc = Util.AddNote("DsPdf AIアシスタントを使用して抽出した表データ", page);
                DrawTable(task.Result, page.Graphics, rc.X, rc.Bottom + 18, page.Size.Width, page.Size.Height);
            }
            catch (Exception ex)
            {
                // エンドポイント、APIキーの割り当てを確認してください。
                Util.CreatePdfError(doc, ex.Message);
            }
            doc.Save(stream);
            return doc.Pages.Count;
        }

        static void DrawTable(Table table, GcGraphics g, float x, float y, float pageWidth, float pageHeight)
        {
            var host = new LayoutHost();
            var view = host.CreateView(pageWidth, pageHeight);

            var rt = view.CreateRect();
            rt.AnchorTopLeft(null, y, x);

            var ta = new TableRenderer(g,
                rt, FixedTableSides.TopLeft,
                rowCount: table.Rows.Count,
                columnCount: table.Cols.Count,
                gridLineColor: Color.DarkGray,
                gridLineWidth: 1,
                rowMinHeight: 10);

            ta.DefaultCellStyle = new CellStyle
            {
                MaxWidth = pageWidth / table.Cols.Count, // 一部の列が狭くなることを想定した推測
                TextAlignment = TextAlignment.Leading,
                PaddingTopBottom = 3,
                PaddingLeftRight = 4,
                FixedWidth = false,
                TextFormat = new TextFormat
                {
                    Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Regular.ttf")),
                    FontSize = 16,
                    FontSizeInGraphicUnits = true
                }
            };

            for (int i = 0; i < table.Rows.Count; ++i)
            {
                for (int j = 0; j < table.Cols.Count; ++j)
                {
                    ta.AddCell(i, j, table.Rows[i].Cells[j].Text);
                }
            }

            ta.ApplyCellConstraints();
            ta.Render();
        }

        public static List<string[]> GetSampleParamsList()
        {
            // 項目は次の通りです: name、description、info、PDF name、AI request
            return
            [
                new string[] { "@ai-table/Invoice Items", "請求書ドキュメント内の表から商品データを取得する", "",
                    "zugferd-invoice.pdf", "ドキュメント内の表から1行目から5行目までのデータを取得してください。" },
                new string[] { "@ai-table/Projected Payments", "ローン完済に関する書類から「Projected Payments」の表を抽出する", "",
                    "LoanClosure.pdf", "Get the '当該ドキュメントに記載されている Projected Payments の表。" },
                new string[] { "@ai-table/Expenses (Top 3 Rows)", "経費報告書の表から最初の3行を取得する", "",
                    "ExpenseReport.pdf", "ドキュメント内の「Expenses」テーブルの最初の3行を取得してください。" },
            ];
        }
    }
}