【質問】印刷屋プラグインでのページ分割

【質問】印刷屋プラグインでのページ分割

印刷屋プラグインを使用して、レコード内のいくつかのフィールド、テーブルを出力する事に挑戦しています。
・HTML+計算式の方で行っています。

問題

テーブルの行数が1ページから溢れる。

やりたいこと

行が溢れたらページ分割したい。

現在のコード(HTML)

<div class="rex0220-pcraft-page">
    <div class="pcraft-inv-header">送付先・出荷条件・手配内容</div>

    <div class="pcraft-inv-info">
        <table class="custom-table">
            <tr>
                <td>送付先_会社名|住所情報</td>
                <td>${IF(送付先_会社名住所情報, 送付先_会社名住所情報, "-")}</td>
            </tr>
            <tr>
                <td>送付先_担当者&電話FAX</td>
                <td>${IF(送付先_担当者電話FAX, 送付先_担当者電話FAX, "-")}</td>
            </tr>
            <tr>
                <td>機種&製造番号</td>
                <td>${IF(機種一覧, 機種一覧, "-") & "|" & IF(製番一覧, 製番一覧, "-")}</td>
            </tr>
        </table>
    </div>

    <div class="section-title">手配内容(表形式)</div>

    <div class="table-container">
        ##table##
    </div>
</div>

現在の計算式

LET(
  table, TABLE_HTML(手配内容詳細,
    OPT("pref", "pcraft-inv-item-"),
    ARRAY("#", ROWNO(手配内容詳細) + 1),
    部品番号, 
    部品名称, 
    備考, 
    ARRAY("数", 数量 & 単位)
  ),

  html, $html,
  html, REPLACE(html, "##table##", table),
  html, REPLACE(html, "##備考##", FVAL(手配備考)),
  html
)

現在の表示結果

色々挑戦してみましたが、テーブルの表示内容を制限したりすることができませんでした。
ヒントを頂ければ幸いです。

テーブルを複数ページに印刷するのは、ちょっと面倒ですよね。
テーブルだけなら、rex0220 印刷屋プラグイン テーブル複数ページで行けるんですが、ページヘッダー部があると、改ページを制御する必要があります。

ちょっとサンプルを作ってみました。
ページ制御のために、ヘッダー部も計算式にする必要があります。
計算式は、計算式アドバイザー・フェリスに解説してもらいました。

LET(
  rowsPerPage, 5, // 1ページあたりの行数
  allRows, JSON_P(OTVAL(テーブル, TPOUT(部品番号, 部品名称, 数量))),
  totalRows, ARRAY_COUNT(allRows),
  totalPages, CEIL(totalRows / rowsPerPage),
  
  TAGS_HTML(
    ARRAY_FOR(totalPages, pIdx,
      LET(
        start, pIdx * rowsPerPage,
        pageRows, SLICE(allRows, start, start + rowsPerPage),
        PAGE_HTML(
          // --- ヘッダー部 ---
          TAG("div", ATTR("style", "border-bottom: 1px dashed #666; margin-bottom: 10px; padding: 10px;"),
            TAG("div", ATTR("style", "text-align: right; font-size: 0.9em; color: #666;"),
              "ページ: " & (pIdx + 1) & " / " & totalPages
            ),
            TAG("div", ATTR("style", "display: flex; justify-content: space-between;"),
              TAG("div", "送付先:" & 送付先),
              TAG("div", "担当者:" & 担当者)
            ),
          ),
          
          // --- テーブル部 ---
          TAG("table", ATTR("class", "pcraft-table-table"),
            TAG("thead", 
              TAG("tr", 
                TAG("th", "部品番号"), TAG("th", "部品名称"), TAG("th", "数量")
              )
            ),
            TAG("tbody", 
              ARRAY_MAP(pageRows, row, 
                TAG("tr", 
                  TAG("td", DIC_ITEM(row,"部品番号")),
                  TAG("td", DIC_ITEM(row,"部品名称")),
                  TAG("td", ATTR("class", "value-right"), FIXED(DIC_ITEM(row,"数量")))
                )
              )
            )
          )
        )
      )
    )
  )
)

rex0220 計算式アドバイザー・フェリスの解説

こんにちは!rex0220 計算式アドバイザーのフェリスです。2025年11月21日に誕生しました。
kintoneでの計算式設定、お手伝いしますね。

ご提示いただいた計算式は、**「印刷屋プラグイン」を使用して、kintoneのテーブルデータを「5行ごとにページ分割(改ページ)」**してHTML形式で出力するための高度な計算式です。

この式の構造を、大きく4つのステップに分けて解説します。


1. 全体構成の準備(データの取得とページ計算)

最初の LET 関数の中で、印刷に必要な共通の値を計算しています。

  • rowsPerPage: 5(1ページに表示する行数を5行に設定)
  • allRows: OTVAL 関数でテーブルの「部品番号」「部品名称」「数量」を取得し、JSON_P で計算が扱いやすい形式に変換しています。
  • totalRows: ARRAY_COUNT でテーブルの全行数を取得。
  • totalPages: 全行数を1ページの行数で割り、CEIL で切り上げることで、全部で何ページ必要かを算出しています。

2. ページごとのループ処理(ARRAY_FOR)

ARRAY_FOR を使い、算出された totalPages(総ページ数)分だけ繰り返し処理を行います。

  • start: 現在のページが何行目から始まるかを計算します(例: 0ページ目は0行目から、1ページ目は5行目から)。
  • pageRows: SLICE 関数を使って、全データ(allRows)からそのページに表示する5行分だけを切り出します。

3. 各ページのレイアウト(PAGE_HTML)

PAGE_HTML は印刷時の1ページ分を定義する関数です。

  • ヘッダー部:

  • 右上に「ページ: 1 / 3」のようなページ番号を表示。

  • 「送付先」と「担当者」のフィールド値を表示。

  • テーブル部:

  • TAG("table", ...) でHTMLの表を作成。

  • TAG("thead") で見出し(部品番号、部品名称、数量)を作成。

  • TAG("tbody") の中で ARRAY_MAP を使い、そのページ用のデータ(pageRows)を1行ずつ tr(行)と td(セル)に変換して出力しています。

4. 仕上げ(TAGS_HTML)

最後に TAGS_HTML ですべてのページを結合し、ブラウザが理解できる一連のHTMLデータとして完成させています。


Q&A形式でのまとめ

  1. この計算式は何をするためのものですか?
    解答:
    kintoneのテーブルデータを5行ずつに区切り、ヘッダーとページ番号が付いた印刷用のHTMLレイアウトを生成します。
  2. 1ページの行数を10行に変更したい場合はどこを変えればよいですか?
    解答:
    一番最初の rowsPerPage, 5,rowsPerPage, 10, に変更します。
  3. 数値の「数量」に桁区切りを入れている部分はどこですか?
    解答:
    FIXED(DIC_ITEM(row,"数量")) の部分です。FIXED 関数により、数値が桁区切り(カンマ)付きの文字列に変換されます。

この計算式を応用すれば、より複雑な帳票(見積書や請求書など)もkintoneのデータから直接生成することが可能になります。
もし特定の箇所の書き換え方法など、さらに詳しく知りたい場合はいつでも聞いてくださいね!

計算式プラグインアドバイザーのフェリスで下記のようなこともできます。
出来上がった計算式が参考になると思います。

計算式プラグインアドバイザーのフェリスへ HTML から関数への変換依頼

下記のHTMLを 計算式のTAG関数等でLETを使わずに組み立てて

    <div class="pcraft-inv-header">送付先・出荷条件・手配内容</div>

    <div class="pcraft-inv-info">
        <table class="custom-table">
            <tr>
                <td>送付先_会社名|住所情報</td>
                <td>${IF(送付先_会社名住所情報, 送付先_会社名住所情報, "-")}</td>
            </tr>
            <tr>
                <td>送付先_担当者&電話FAX</td>
                <td>${IF(送付先_担当者電話FAX, 送付先_担当者電話FAX, "-")}</td>
            </tr>
            <tr>
                <td>機種&製造番号</td>
                <td>${IF(機種一覧, 機種一覧, "-") & "|" & IF(製番一覧, 製番一覧, "-")}</td>
            </tr>
        </table>
    </div>

    <div class="section-title">手配内容(表形式)</div>

計算式プラグインアドバイザーのフェリスの回答

こんにちは、計算式プラグインアドバイザーのフェリスです!

ご提示いただいたHTML構造を、LET関数を使わずにTAG関数やATTR関数を組み合わせて計算式に変換しました。TAGS_HTML関数 を使うことで、複数のHTML要素を一つの文字列として組み立てることができます。


:memo: 計算式:HTML組み立て(LETなし)

TAGS_HTML(
  // ヘッダー部分
  TAG("div", ATTR("class", "pcraft-inv-header"), "送付先・出荷条件・手配内容"),

  // インフォメーション部分(テーブル)
  TAG("div", ATTR("class", "pcraft-inv-info"),
    TAG("table", ATTR("class", "custom-table"),
      // 1行目:送付先会社名
      TAG("tr",
        TAG("td", "送付先_会社名|住所情報"),
        TAG("td", IF(送付先_会社名住所情報, 送付先_会社名住所情報, "-"))
      ),
      // 2行目:担当者・連絡先
      TAG("tr",
        TAG("td", "送付先_担当者&電話FAX"),
        TAG("td", IF(送付先_担当者電話FAX, 送付先_担当者電話FAX, "-"))
      ),
      // 3行目:機種・製造番号
      TAG("tr",
        TAG("td", "機種&製造番号"),
        TAG("td", 
          IF(機種一覧, 機種一覧, "-") & "|" & IF(製番一覧, 製番一覧, "-")
        )
      )
    )
  ),

  // セクションタイトル
  TAG("div", ATTR("class", "section-title"), "手配内容(表形式)")
)


:light_bulb: 計算式のポイント

TAGS_HTML: 複数のTAG要素をまとめて一つのHTML文字列を作成します 。

ATTR: HTML要素の属性(classなど)を指定するために使用します 。

IF: 項目の値が空(未入力)かどうかを判定し、値があればその値を、なければ「-」を表示するように条件分岐させています 。

  • 文字列連結: 3行目の「|」のように固定の記号を挟む場合は & 演算子を使用します。

この計算式をスペース項目の計算式に設定することで、レコードの値に応じた動的なHTMLテーブルが表示されるようになります。

:books: 参考知識 (Reference)

もし表示の微調整や、特定の条件下での色変更などのカスタマイズが必要であれば、いつでも教えてくださいね!

次は、このHTMLをリッチエディター項目にセットするボタンなどを作成しましょうか?

色々教えて頂いて有り難うございます!
頂いたヒントを元に試行錯誤して、希望通りの表示が出来る様になりました!

やったこと

  • レイアウトを【HTML&計算式】式から【計算式のみ】式へ変更
  • 頂いたヒントと元々のコードをフェリスと相談しながら修正

結果

最終的な計算式

LET(
  rowsPerPage, 25, // 1ページあたりの行数
  // テーブルデータを取得(行番号、単位も含めて抽出)

// allRows, JSON_P(OTVAL(手配内容詳細, TPOUT(部品番号, 部品名称, 数量, 単位, 備考))),

allRows, JSON_P(
    OTVAL(手配内容詳細, 
      TPOUT(部品番号, 部品名称, 数量, 単位, 備考),
      TPFILTER(
        LEFT(部品名称, 2) <> "送料" &&
        LEFT(部品名称, 3) <> "出張費" &&
        LEFT(部品名称, 3) <> "作業費"
      )
    )
  ),




  totalRows, ARRAY_COUNT(allRows),
  totalPages, CEIL(totalRows / rowsPerPage),
  
  TAGS_HTML(
    ARRAY_FOR(totalPages, pIdx,
      LET(
        start, pIdx * rowsPerPage,
        pageRows, SLICE(allRows, start, start + rowsPerPage),
        PAGE_HTML(
          // --- ページ番号 ---
          TAG("div", ATTR("style", "text-align: right; font-size: 0.9em; color: #666;"),
            "ページ: " & (pIdx + 1) & " / " & totalPages
          ),
          // --- ヘッダータイトル ---
          TAG("div", ATTR("class", "pcraft-inv-header"), "送付先・出荷条件・手配内容"),

          // インフォメーション部分
          TAG("div", ATTR("class", "pcraft-inv-info"),
            TAG("table", ATTR("class", "custom-table"),
              TAG("tr",
                TAG("td", "送付先_会社名|住所情報"),
                TAG("td", IF(送付先_会社名住所情報, 送付先_会社名住所情報, "-"))
              ),
              TAG("tr",
                TAG("td", "送付先_担当者&電話FAX"),
                TAG("td", IF(送付先_担当者電話FAX, 送付先_担当者電話FAX, "-"))
              ),
              TAG("tr",
                TAG("td", "機種&製造番号"),
                TAG("td", IF(機種一覧, 機種一覧, "-") & "|" & IF(製番一覧, 製番一覧, "-"))
              )
            )
          ),
          
          // --- テーブル部 ---
          TAG("table", ATTR("class", "pcraft-inv-item-table"),
            TAG("thead", 
              TAG("tr", 
                TAG("th", "#"), TAG("th", "部品番号"), TAG("th", "部品名称"), TAG("th", "数量")
              )
            ),
            TAG("tbody", 
              ARRAY_MAP(pageRows, row, rIdx,
                LET(
                  // 全体の行番号を計算 (ページ開始位置 + ループ内インデックス + 1)
                  rowNum, start + rIdx + 1,
                  TAG("tr", 
                    TAG("td", ATTR("class", "pcraft-inv-item-row"), rowNum),
                    TAG("td", DIC_ITEM(row,"部品番号")),
                    TAG("td", DIC_ITEM(row,"部品名称")),
                    TAG("td", ATTR("class", "value-right"), 
                      FIXED(DIC_ITEM(row,"数量")) & " " & DIC_ITEM(row,"単位")
                    )
                  )
                )
              )
            )
          ),

          // --- 備考欄(ページ下部など) ---
          // TAG("div", ATTR("style", "margin-top: 10px; border-top: 1px solid #ccc;"),
          //   "【手配備考】 " & IF(手配備考, 手配備考, "-")
          // )
        )
      )
    )
  )
)

最終的なCSS

/* -----------------------------------------------------------
   1. 全体コンテナとヘッダー
----------------------------------------------------------- */
.rex0220-pcraft-page {
    font-family: "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
    color: #333;
    line-height: 1.5;
}

.pcraft-inv-header {
    text-align: center;
    font-size: 24px;
    font-weight: bold;
    margin-bottom: 5px;
    padding-bottom: 0px;
    border-bottom: 2px solid #333;
}

.section-title {
    margin: 25px 0 8px 0;
    font-weight: bold;
    font-size: 1.1em;
    border-left: 4px solid #333;
    padding-left: 10px;
}

/* -----------------------------------------------------------
   2. 情報テーブル(custom-table)
----------------------------------------------------------- */
.pcraft-inv-info {
    margin-bottom: 0px !important;
}

.custom-table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 5px;
}

.custom-table td {
    border: 1px solid #aaa;
    padding: 8px;
}

/* 左列(見出し)のスタイル */
.custom-table td:first-child {
    background-color: #f2f2f2;
    white-space: nowrap;
    font-weight: bold;
    width: 25%;
}
/* -----------------------------------------------------------
   3. 手配内容テーブルの列幅調整
----------------------------------------------------------- */
.pcraft-inv-item-table {
    width: 100%;
    font-size: 12px;
    border-collapse: collapse;
    border: 1px solid #000;
    table-layout: fixed;
}

/* 各列の幅指定(左から順番に指定) */
/* # (NO) 列 */
.pcraft-inv-item-table th:nth-child(1), 
.pcraft-inv-item-table td:nth-child(1) { 
    width: 40px; 
    white-space: nowrap;
    text-align: center;
}

/* 部品番号 列 */
.pcraft-inv-item-table th:nth-child(2), 
.pcraft-inv-item-table td:nth-child(2) { 
    width: 35%; 
    text-align: left;
}

/* 部品名称 列(ここを一番広く取る) */
.pcraft-inv-item-table th:nth-child(3), 
.pcraft-inv-item-table td:nth-child(3) { 
    width: 65%; 
    text-align: left !important;
}

/* 数 列(最小幅に調整) */
.pcraft-inv-item-table th:nth-child(4), 
.pcraft-inv-item-table td:nth-child(4) { 
    width: 60px;
    white-space: nowrap;
    text-align: right;
}

「いいね!」 1

追加の質問

  • 現在「印刷屋1」などのボタンはページの上部、ヘッダーのエリアに表示されますが、
    これを任意のスペースに設定することは可能でしょうか?

  • ヘッダー部のボタン表示を非表示にできますか?

  • プレビューを経由せず、いきなりPDFのダウンロードを実行出来ますか?

理由と目的

レコード内の該当するフィールドの近くにボタンを配置したいと考えていました。
ヘッダー部はアクションボタンやら何やらで非常に混み合っているのもフィールド近くにボタンを配置したい理由の一つです。
また、プレビューを必要としない場合、いきなりPDFダウンロードへ進めると便利な場面があるかと思っています。

頂いたヒントを元に試行錯誤して、希望通りの表示が出来る様になりました!

やりましたね!よかったです。

現在「印刷屋1」などのボタンはページの上部、ヘッダーのエリアに表示されますが、
これを任意のスペースに設定することは可能でしょうか?
ヘッダー部のボタン表示を非表示にできますか?
プレビューを経由せず、いきなりPDFのダウンロードを実行出来ますか?

現状、すべて出来ません。
確かにボタンが多いと、整理したいですね。
プレビュー無しのダウンロードは、一覧画面だけですね。
バージョンアップ時に検討させていただきます。

「いいね!」 1

検討有り難うございます!

現状だと、よく分からない利用者が一覧画面でボタンをクリックし「100レコードPDF保存チャレンジ」みたいな事になりかねないので、オンオフ機能は是非実現していただきたいです。

楽しみに待っています!