LoginSignup
0
0

More than 1 year has passed since last update.

DataSpiderSDKによるPDFアダプタの実装

Last updated at Posted at 2023-01-01

DataSpiderとブロックチェーン その9

前回は、NFT連携するためのDataSpiderによりシナリオについて紹介しました。
今回からNFT連携に必要となるアダプタの実装について紹介したいと思います。

やること

シナリオの❷ (※前回の記事で紹介しましたシナリオは以下の図を参照ください) で必要となるPDF生成の実装していきます。
PDFを生成するアダプタを作成したいと思います。
NFTシナリオ_vol1.PNG

開発環境

前回から同様のWindows10上で行います。
DataSpiderもWindows版(体験版を使用)を用意ください。

ライブラリの準備

今回は、あたらにPDF生成のためのJavaライブラリをインストールします。
iTextのライブラリを取得します。
Java1.8でコンパイルする場合は、こちらのiText7 Githubから入手ください。
執筆時点では、iText Ver7.2.4を使用します。

iText7のビルド

git clone https://github.com/itext/itext7.git
cd itext7
git checkout 7.2.4
mvn clean install -D maven.test.skip=true

ビルドツール
Apache Maven 3.8.6
Maven home: C:\apache-maven-3.8.6-bin\apache-maven-3.8.6
Java version: 1.8.0_202, vendor: Oracle Corporation, runtime: C:\java\8\jre
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

iText ライブラリ群

itext7-barcodes-7.2.4.jar
itext7-commons-7.2.4.jar
itext7-font-asian-7.2.4.jar
itext7-forms-7.2.4.jar
itext7-hyph-7.2.4.jar
itext7-io-7.2.4.jar
itext7-kernel-7.2.4.jar
itext7-layout-7.2.4.jar
itext7-pdfa-7.2.4.jar
itext7-pdftest-7.2.4.jar
itext7-sign-7.2.4.jar
itext7-styled-xml-parser-7.2.4.jar
itext7-svg-7.2.4.jar

iTextとは

PDFデータを生成するためのライブラリです。
フリー版(AGPLライセンス)と商用版が提供されています。
ライブラリは、Java言語と.NETの2種類があります。今回の検証では、Java言語用のライブラリを使用します。
公式ホームページ:https://itextpdf.com/products/itext-7
ナレッジサイトから色々な実装例を探すことができます。
ナレッジサイト:https://kb.itextpdf.com/home

アダプタの実装

PDFアダプタの利用イメージ

NFTアダプタイメージ2.PNG
PDFアダプタの処理概要:
複数件ある受取者名簿の内容を読み込み1行1ファイルずつPDFファイルを生成します。

  • プロパティ画面で、PDFに埋め込むロゴ画像、PDFファイルの出力先パス、PDFファイル生成時の接頭文字の設定欄を設けます。
  • PDFに埋め込む文字列を受け取ります。
  • 受け取った文字列と指定されたロゴ画像をPDFに埋め込みます。
  • 指定されたパスにPDFファイルを出力します。
  • 出力したファイル名をアドレスIDと共に後続のアダプタ向けの出力項目に格納します。

PDF出力部分のソースコード

ソースの構成

PDF出力処理をPutTronGeneratePdfOperation.javaに実装します。
PDFソース_1.PNG

iTextのライブラリを参照ライブラリの外部jarとして追加します。
PDFソース_2.png

PutTronGeneratePdfOperation.java


@Override
public Map execute(Map inputData) throws Exception {
    Map res = new HashMap();

    FileManager fm = (FileManager) getContext().getProxy(FileManager.class);

    String imagePath = getImagePath();
    String pdfOutputPath = getPdfOutputPath();
    String pdfPrefix = getPdfPrefix();

    LocalDateTime now = LocalDateTime.now();
    DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd");
    String payoutDate = now.format(dateFormat);

    Object data = inputData.get(KEY_INPUT);

    LoggingContext log = getContext().log();

    // 出力側TableDataBuilderを生成する。
    TableDataBuilder builder = DataBuilderFactory.newTableDataBuilder(getColumnOutputTypes(), isLargeData());

    log.info(builder.toString());

    try (TableRowIterator rowIterator = DataParserFactory.newTableRowIterator(data)) {

        // 出力側項目の出力開始を宣言する
        builder.startConstruction();

        // 入力側レコードの繰り返し処理
        while (rowIterator.hasNext()) {
            Row record = rowIterator.next();

            builder.startRow(); // 出力側行単位のデータを格納するバッファ

            /*
             * 入力側データ読み込み
             */
            Column userIdColumn = record.getColumn(0);
            String userId = getColumnValue(userIdColumn);

            Column nameColumn = record.getColumn(1);
            String name = getColumnValue(nameColumn);

            Column addressColumn = record.getColumn(2);
            String publicAddress = getColumnValue(addressColumn);

            String dest = pdfOutputPath + "/" +  pdfPrefix + publicAddress + ".pdf";

            /*
             * PDF出力
             * 必要に応じてPDFテンプレートを読み込んでPDFを生成するロジックにする
             */
            int counter = 1;

            // 日本語対応のフォントを指定
            PdfFont fontDetail = PdfFontFactory.createFont("HeiseiKakuGo-W5", "UniJIS-UCS2-H");

            PdfWriter writer = new PdfWriter(fm.getOutputStream(dest));
            PdfDocument pdf = new PdfDocument(writer);
            pdf.setDefaultPageSize(PageSize.A6.rotate());
            Document doc = new Document(pdf);

            // SVGファイルのみ対応
            Image myLogo = SvgConverter.convertToImage(fm.getInputStream(imagePath), pdf);

            Paragraph p = new Paragraph("")
                    .add(myLogo);
            p.setTextAlignment(TextAlignment.CENTER);
            p.setVerticalAlignment(VerticalAlignment.TOP);
            doc.add(p);

            float[] columnWidths = {1, 4, 8};
            Table table = new Table(UnitValue.createPercentArray(columnWidths));
            Cell cell = new Cell(1, 3)
                    .add(new Paragraph("CERTIFICATE OF COMPLETION"))
                    .setWidth(1000)
                    .setFont(fontDetail)
                    .setFontSize(13)
                    .setFontColor(ColorConstants.WHITE)
                    .setBackgroundColor(ColorConstants.BLACK)
                    .setTextAlignment(TextAlignment.CENTER);

            table.addHeaderCell(cell);

            // 証明書の内容を1行ずつ生成する
            table.addCell(new Cell().setTextAlignment(TextAlignment.CENTER).add(new Paragraph(String.valueOf(counter++))));
            table.addCell(new Cell().setTextAlignment(TextAlignment.LEFT).add(new Paragraph("発行年月日").setFont(fontDetail).setFontSize(10)));
            table.addCell(new Cell().setTextAlignment(TextAlignment.LEFT).add(new Paragraph(payoutDate).setFontSize(10)));

            table.addCell(new Cell().setTextAlignment(TextAlignment.CENTER).add(new Paragraph(String.valueOf(counter++))));
            table.addCell(new Cell().setTextAlignment(TextAlignment.LEFT).add(new Paragraph("受講者").setFont(fontDetail).setFontSize(10)));
            table.addCell(new Cell().setTextAlignment(TextAlignment.LEFT).add(new Paragraph(name).setFont(fontDetail).setFontSize(10)));

            table.addCell(new Cell().setTextAlignment(TextAlignment.CENTER).add(new Paragraph(String.valueOf(counter++))));
            table.addCell(new Cell().setTextAlignment(TextAlignment.LEFT).add(new Paragraph("TRONアドレス").setFont(fontDetail).setFontSize(10)));
            table.addCell(new Cell().setTextAlignment(TextAlignment.LEFT).add(new Paragraph(publicAddress).setFontSize(10)));

            doc.add(table);

            doc.add(new Paragraph("上記受講者は、" + payoutDate + "をもって受講修了したことを証明します").setFont(fontDetail).setFontSize(10));

            doc.close();

            /*
             * 出力側項目格納
             */
            // UserID
            builder.column(userId);
            log.debug("UserID = " + userId);
            // senderAddress
            builder.column(publicAddress);
            log.debug("publicAddress = " + publicAddress);
            // fileName
            builder.column(pdfPrefix + publicAddress + ".pdf");
            log.debug("fileName = " + pdfPrefix + publicAddress + ".pdf");
            // 出力時間
            builder.column(payoutDate);

            builder.endRow();

        }

        builder.endConstruction();
        Object result = builder.getResult();

        res.put(KEY_OUTPUT, result);

    }

    return res;
}

PDF生成アダプタの設定項目

PDF生成アダプタのプロパティ画面

pdfアダプタ設定項目.PNG

TronGeneratePdfOperationFactory.java

画面のプロパティ情報を実装します。

public abstract class TronGeneratePdfOperationFactory implements OperationFactory {

	@Override
	public OperationConfigurator createOperationConfigurator(
			OperationConfiguration conf,
			OperationContext context) throws Exception {

		OperationConfigurator configurator = new OperationConfigurator(conf, context);

		configurator.addGroup(new ParameterGroup(KEY_MUST_GROUP, MultiLangMessage.getString("group.type.label")));

		configurator.addSimpleParameter(KEY_MUST_GROUP, createImagePathParameter());
		configurator.addSimpleParameter(KEY_MUST_GROUP, createPdfOutputPathParameter());
		configurator.addSimpleParameter(KEY_MUST_GROUP, createPdfPrefixParameter());

		return configurator;
	}

	private SimpleParameter createImagePathParameter() {
		Fillin constraint = new Fillin();
		constraint.setLabel("PDFロゴパスファイル名");
		constraint.setRequired(false);
		constraint.setShortcut("L");
		constraint.setLength(1024);
		constraint.setDescription("1024 文字以内で設定してください");
		SimpleParameter param = new SimpleParameter(KEY_IMAGE_PATH, constraint);
		return param;
	}

	private SimpleParameter createPdfOutputPathParameter() {
		Fillin constraint = new Fillin();
		constraint.setLabel("PDF出力パス");
		constraint.setRequired(false);
		constraint.setShortcut("S");
		constraint.setLength(1024);
		constraint.setDescription("1024 文字以内で設定してください");
		SimpleParameter param = new SimpleParameter(KEY_PDF_OUTPUT_PATH, constraint);
		return param;
	}

	private SimpleParameter createPdfPrefixParameter() {
		Fillin constraint = new Fillin();
		constraint.setLabel("PDFファイルプレフィックス");
		constraint.setRequired(false);
		constraint.setShortcut("P");
		constraint.setLength(1024);
		constraint.setDescription("1024 文字以内で設定してください");
		SimpleParameter param = new SimpleParameter(KEY_PDF_PREFIX, constraint);
		return param;
	}

	String createInputSchema(OperationConfiguration conf) {
		TableSchemaGenerator generator = new TableSchemaGenerator();

		// 入力側の項目名称(固定)
		String address_id = KEY_INPUT_COLNAME_ADDRESS_ID;
		// 入力側の項目タイプ(固定)
		String address_id_type = TYPE_STRING;

		generator.addColumn(address_id, TableDataTypeUtil.parseType(address_id_type));

		// 入力側の項目名称(固定)
		String name = KEY_INPUT_COLNAME_NAME;
		// 入力側の項目タイプ(固定)
		String name_type = TYPE_STRING;

		generator.addColumn(name, TableDataTypeUtil.parseType(name_type));

		// 入力側の項目名称(固定)
		String address = KEY_INPUT_COLNAME_ADDRESS;
		// 入力側の項目タイプ(固定)
		String address_type = TYPE_STRING;

		generator.addColumn(address, TableDataTypeUtil.parseType(address_type));

		// 文字列として XMLSchema を返します。
		return generator.generateXMLSchema();
	}

	String createOutputSchema(OperationConfiguration conf) {
		TableSchemaGenerator generator = new TableSchemaGenerator();

		// 出力側の項目名称(固定)入力側のアドレスIDを格納
		String name = KEY_OUTPUT_COLNAME_ADDRESS_ID;
		// 出力側の項目タイプ(固定)
		String type = TYPE_STRING;
		generator.addColumn(name, TableDataTypeUtil.parseType(type));

		// 出力側の項目名称(固定) 入力側のアドレスを格納
		name = KEY_OUTPUT_COLNAME_ADDRESS;
		// 出力側の項目タイプ(固定)
		type = TYPE_STRING;
		generator.addColumn(name, TableDataTypeUtil.parseType(type));

		// 出力側の項目名称(固定) PDF出力パスファイル名を格納
		name = KEY_OUTPUT_COLNAME_PDF_OUTPUT_PATH;
		// 出力側の項目タイプ(固定)
		type = TYPE_STRING;
		generator.addColumn(name, TableDataTypeUtil.parseType(type));

		// 出力側の項目名称(固定) PDF発行日を格納
		name = KEY_OUTPUT_COLNAME_PDF_PAYOUT_DATE;
		// 出力側の項目タイプ(固定)
		type = TYPE_STRING;
		generator.addColumn(name, TableDataTypeUtil.parseType(type));

		// 文字列として XMLSchema を返します。
		return generator.generateXMLSchema();
	}
}

その他、画面から項目を取得するメソッドやアダプタアイコンを作成します。

詳細は、コンポーネントSDK 4.2 開発ガイドを参照ください。

  • 画面項目の実装:5.2. MessageXML Adapter の作成
  • アイコンの生成:18. オペレーションとグローバルリソースのアイコンファイルについて

DataSpiderスクリプトの作成

PDF出力アイコンが今回実装したアダプタです。
その前後のアイコンのマッピング状態を以下に記します。

全体像

pdfスクリプト_1.PNG

PDF出力マッピング(PDF出力アイコンの入力側マッピング)

pdfスクリプト_2.PNG

出力結果マッピング(PDF出力アイコンの出力側マッピング)

pdfスクリプト_3.PNG

入出力ファイルと出力結果

image.png

証明書PDFファイル

image.png

image.png

PDFアダプタの実装と動作結果は以上です。

次回は

IPFS/NFT部分の実装を行います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0