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

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

準備

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

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

日本語フォントの準備

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

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

コード

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using iTextSharp.text;
using iText.Kernel.Pdf;
using iTextSharp.text.pdf;
using System.Net;
using System.Net.Http.Headers;

namespace iTextPdfTest
{
    public class Function1
    {
        [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にブラウザからアクセスすると出てくることが確認できます!

コメント

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