[Azure Functions][C#] iTextSharpでPDF出力してみた。

C# C#

Azure FunctionsでiTextSharpを使ってPDF出力しました!
日本語出力もフォントファイルを取ってきて、出てくることを確認しました。
ここでは0から作っていますが、テンプレートを使って出力することも可能なことを確認しています。
いくつか参考にさせてもらったリンクを下部に貼っています。

準備

パッケージのインストール

iTextSharpをNuGetパッケージマネージャからダウンロードしてきます。
Windowsだとツール=>NuGetパッケージマネージャ=>ソリューションのNuGetパッケージの管理からいけます。
そうするとこんな感じになります。

※iTextは必要なくて、一緒に使うとメソッド名などが被っておかしなことになるので気を付けてください。

日本語フォントの準備

https://www.fontpalace.com/font-details/MS+Gothic/
から日本語フォントをダウンロードしてきました。

落としてきたら、ソリューションエクスプローラーからでもフォルダから直接でもいいかと思いますが、プロジェクトから参照できる位置に置きます。
今回はプログラムファイルと同じ場所に配置しました。

ファイルを右クリックして、プロパティから出力ディレクトリに常にコピーを設定しておきます。
これで、Debug配下の実行ファイルに含めてビルドされるようです。

コード

using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace iTextPdfTest
{
    public class iTextSharpFunction
    {
        [FunctionName("TestPdfOutput")]
        public HttpResponseMessage TestPdfOutput(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "test_output_pdf")] HttpRequest req,
            ILogger log
            )
        {
            // 日本語を使う場合に下記三行が必要:
            // エラー解消:'windows-1252' is not a supported encoding name.
            System.Text.EncodingProvider encodingProvider;
            encodingProvider = System.Text.CodePagesEncodingProvider.Instance;
            Encoding.RegisterProvider(encodingProvider);

            // A4横でドキュメントを作成
            var doc = new Document(PageSize.A4.Rotate());
            var ms = new MemoryStream();

            //ファイルの出力先を設定
            var pw = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, ms);

            //ドキュメントを開く
            doc.Open();

            var pdfContentByte = pw.DirectContent;
            //var bf = BaseFont.CreateFont(BaseFont.TIMES_BOLD, BaseFont.WINANSI, BaseFont.EMBEDDED);
            var bf = BaseFont.CreateFont(@"MS Gothic.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            // ベースフォントとフォントサイズを指定する。
            pdfContentByte.SetFontAndSize(bf, 10);

            // 指定箇所に文字列を記述
            ShowTextAligned(pdfContentByte, 10, 500, "Test Pdf Output");
            ShowTextAligned(pdfContentByte, 10, 480, "日本語の出力テスト。");
            DrawLine(pdfContentByte, 2, 451, 840, 451);

            doc.Close();

            /*-- ファイル出力
            using (BinaryWriter w = new BinaryWriter(File.OpenWrite(@"result.pdf")))
            {
                w.Write(ms.ToArray());
            }
            --*/

            // レスポンス作成
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(ms.GetBuffer())
            };

            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = "testhoge.pdf"
            };

            response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");

            return response;
        }

        private void ShowTextAligned(PdfContentByte pdfContentByte, float x, float y, string text, int alignment = Element.ALIGN_LEFT, float rotaion = 0)
        {
            pdfContentByte.BeginText();
            pdfContentByte.ShowTextAligned(alignment, text, x, y, rotaion);
            pdfContentByte.EndText();
        }

        private static void DrawLine(PdfContentByte pdfContentByte, float fromX, float fromY, float toX, float toY)
        {
            pdfContentByte.MoveTo(fromX, fromY);
            pdfContentByte.LineTo(toX, toY);
            pdfContentByte.ClosePathStroke();
        }
    }
}

コードの説明

関数始まって、最初の三行は 「windows-1252′ is not a supported encoding name.」というエラーが出たので、解消のためにいれました。Windowsだとエラー出ないかもしれません。

DocumentとMemoryStreamを作って、ドキュメントオープン後にフォントの設定をして、文字を配置するといった流れです。
ほとんど、参照させていただいたリンク先と同じです。

つまずいたのが、HttpResponseを返すところが変わらなかったので、時間がかかりました。。

var response = new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new ByteArrayContent(ms.GetBuffer())
};

色々やってみると、こんな感じでHttpResponseMessageのContentに入れておけばいいようでした。

参考リンク

Qiita:iTextSharpでPDF出力
Qiita:C# の PDF作成用ライブラリ

動作確認

Azure Functionにブラウザからアクセスすると出てくることが確認できます!

Azure上でリソースファイルがなくてエラーになる。

githubにソースを…

コメント

タイトルとURLをコピーしました