1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

kintoneで指定したpdfファィルを連結して出力する

1
Last updated at Posted at 2026-05-27

複数の添付ファイルフィールドに入力されたPDFファイルを結合して出力したいという要望があったので作成しました

jsライブラリの適応

まず外部ライブラリのPDF-LIBを適応させます
今回は
https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.js
を使用しました
image.png

ソースの作成

こんな感じ。今回は詳細にボタンをつける感じです
※参考にしたサイトをめもるの忘れていたのであとで追加します
※ソースのコメントはそこからコピペしたものもあります

(() => {
  ("use strict");
  kintone.events.on("app.record.detail.show", (event) => {
    const menuButton = document.createElement("button");
    menuButton.id = "menu_button";
    menuButton.innerText = "pdf結合DL";
    menuButton.addEventListener("click", async () => {
      let record = kintone.app.record.get().record;
      //ベースとなるファィルの取得
      if (
        !record["ベースファイル"].value ||
        record["ベースファイル"].value.length != 1
      ) {
        alert(
          "ベースファイルが登録されていない、あるいは複数登録されています。ご確認ください",
        );
        return;
      }

      try {
        const fileKey = record["ベースファイル"].value[0].fileKey;

        const headers = {
          "X-Requested-With": "XMLHttpRequest",
        };
        const resp = await fetch(`/k/v1/file.json?fileKey=${fileKey}`, {
          method: "GET",
          headers,
        });

        const blob = await resp.blob();
        const arrayBuffer = await blob.arrayBuffer();
        // 新しいPDFドキュメントを作成
        const mergedPdf = await PDFLib.PDFDocument.create();
        // 各PDFファイルを処理
        const fileBytes = await blob.arrayBuffer();
        const pdfDoc = await PDFLib.PDFDocument.load(fileBytes);

        // 現在のPDFからすべてのページをコピー
        const copiedPages = await mergedPdf.copyPages(
          pdfDoc,
          pdfDoc.getPageIndices(),
        );

        // コピーした各ページをマージ先のPDFに追加
        copiedPages.forEach((page) => mergedPdf.addPage(page));

        //対象ファイル
        const metaFile = [
          "添付1",
          "添付2",
          "添付3",
          "添付4",
        ];
        Promise.all(
          metaFile.map(async (elementName) => {
            for await (const chunk of record[elementName].value) {
              const fileKey_tmp = chunk.fileKey;
              const fileName_tmp = chunk.name;
              const pos = fileName_tmp.lastIndexOf(".");
              if (pos === -1) {
                continue; //ここはめったに通らないはず
              } else {
                if (fileName_tmp.slice(pos + 1).toLowerCase() != "pdf") {
                  //pdf以外はスルー
                  continue;
                }
              }

              //ここからはpdfであることが前提
              const resp_tmp = await fetch(
                `/k/v1/file.json?fileKey=${fileKey_tmp}`,
                {
                  method: "GET",
                  headers,
                },
              );
              const blob_tmp = await resp_tmp.blob();
              const arrayBuffer_tmp = await blob_tmp.arrayBuffer();

              // 各PDFファイルを処理2
              const fileBytes_tmp = await blob_tmp.arrayBuffer();
              const pdfDoc_tmp = await PDFLib.PDFDocument.load(fileBytes_tmp);

              // 現在のPDFからすべてのページをコピー
              const copiedPages_tmp = await mergedPdf.copyPages(
                pdfDoc_tmp,
                pdfDoc_tmp.getPageIndices(),
              );
              // コピーした各ページをマージ先のPDFに追加
              copiedPages_tmp.forEach((page_tmp) => {
                mergedPdf.addPage(page_tmp);
              });
            }
          }),
        ).then(async () => {
          // マージしたPDFをBlobとして返す
          const mergedPdfBytes = await mergedPdf.save();
          const newBlob = new Blob([mergedPdfBytes], {
            type: "application/pdf",
          });

          const url = window.URL || window.webkitURL;
          const blobUrl2 = url.createObjectURL(newBlob);
          // リンクを作成し、そこにBlobオブジェクトを設定する
          const alink = document.createElement("a");
          alink.textContent = "ダウンロード";
          alink.download = "ダウンロードファイル.pdf";
          alink.href = blobUrl2;
          alink.target = "_blank";

          // マウスイベントを設定
          const e = new MouseEvent("click", {
            view: window,
            bubbles: true,
            cancelable: true,
          });

          // aタグのクリックイベントをディスパッチする
          alink.dispatchEvent(e);
        });
      } catch (err) {
        console.error(err);
      }
    });

    const headerMenuSpace = kintone.app.record.getHeaderMenuSpaceElement();
    headerMenuSpace.appendChild(menuButton);
  
    return event;
  });
})();


1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?