業務データが挿し込まれた HTML から PDF を生成する(DocRaptor 連携)

DocRaptor とは、API 経由で受け取ったソース HTML データを PDF 形式に変換し、PDF ファイルとして返す Web サービスです。Questetra では DocRaptor と連携しPDF ファイルを生成する自動工程が提供されています。

本記事ではビルトイン自動工程「DocRaptor: PDF 生成」の基本的な使い方を説明します。

PDF ファイルを生成する類似の自動工程として、Adobe Acrobat Service API を対象とする[Adobe: PDF 生成(HTML to PDF)]も利用できます。

DocRaptor での準備

DocRaptor の Web サイト(英語のみ)でアカウントを作成します。メールアドレス、氏名、パスワードを入力して[Sign Up]をクリックすると API キーが発行され、「Document History」のページに表示されます。API キーは、[DocRaptor: PDF 生成]の HTTP 認証設定で使います。

DocRaptor の無料アカウントで生成できるドキュメントは、月に 5 つまでです。ワークフローアプリをデバッグ実行したときは、DocRaptor の TEST モードで PDF が生成されます。TEST モードの PDF には DocRaptor のすかしが入りますが、生成数には数えられません。

業務データが挿入されるソース HTML の準備

業務データを挿し込む箇所に SpEL 式を書いた HTML を、この記事では「ソース HTML」と呼びます。

ソース HTML を自動工程[テキストファイル生成]で書き出すと、SpEL 式がデータ項目の値に置き換わり、業務データが挿し込まれた HTML ファイルになります。この HTML ファイルを[DocRaptor: PDF 生成]で PDF に変換します。

SpEL 式の書き方と使える関数は、「R2272: 件名/文字型への自動代入(データ設定式)」を参照してください。

サンプルアプリ

DocRaptor テスト用アプリ

サンプルアプリでは、「データ入力」工程で入力した値を、「HTML ファイル生成」工程([テキストファイル生成])がソース HTML に挿し込んで HTML ファイルに書き出し、「PDF 生成」工程([DocRaptor: PDF 生成])がその HTML ファイルを PDF に変換します。

ソース HTML は、DocRaptor の Free HTML to PDF Templates にある Invoice(請求書)の A4 サイズのテンプレート(invoice.A4.html)を基に作ります。Download A4 Size のリンク先を保存してください。英語の書面なので、日本語に書き換えます。

アプリ設定

データ項目

データ項目は次のとおりです。「HTML File」と「PDF File」以外は、ソース HTML に挿し込むデータ項目です。

データ項目名データ型フィールド名「データ入力」工程での表示説明
HTML Fileファイルq_html非表示「HTML ファイル生成」工程が書き出した HTML ファイルを保存します
PDF Fileファイルq_pdf非表示「PDF 生成」工程が生成した PDF ファイルを保存します
請求先名文字 (単一行)q_billing_name編集可能
請求先住所文字 (複数行)q_billing_address編集可能
請求先アドレス文字 (単一行)q_billing_email編集可能
支払期限日付 (年月日)q_due_date編集可能初期値: #today.addDays(30)
商品名1文字 (単一行)q_item_name1編集可能
備考1文字 (単一行)q_remark1編集可能
単価1数値q_unit1編集可能
数量1数値q_quantity1編集可能
価格1数値q_price1編集可能式: #q_unit1 * #q_quantity1
商品名2文字 (単一行)q_item_name2編集可能
備考2文字 (単一行)q_remark2編集可能
単価2数値q_unit2編集可能
数量2数値q_quantity2編集可能
価格2数値q_price2編集可能式: #q_unit2 * #q_quantity2
商品名3文字 (単一行)q_item_name3編集可能
備考3文字 (単一行)q_remark3編集可能
単価3数値q_unit3編集可能
数量3数値q_quantity3編集可能
価格3数値q_price3編集可能式: #q_unit3 * #q_quantity3
小計数値q_subtotal編集可能式: #q_price1 + #q_price2 + #q_price3
消費税数値q_tax編集可能式: #q_subtotal * 0.1
合計金額数値q_total編集可能式: #q_subtotal + #q_tax
請求書発行日日付 (年月日)q_issue_date編集可能初期値: #today
請求書番号文字 (単一行)q_invoice_id編集可能初期値: #{processInstanceSequenceNumber}

「HTML ファイル生成」工程(テキストファイル生成)

この工程は、「C4: テキストファイルの内容」に登録したソース HTML の SpEL 式をデータ項目の値に置き換え、HTML ファイルとしてデータ項目「HTML File」に保存します。サンプルアプリで設定する内容は次のとおりです。

設定項目サンプルアプリでの設定
C1: テキストファイルを保存するファイル型データ項目「HTML File」
C3: 保存ファイル名source-#{processInstanceId}.html(拡張子は .html にします)
C4: テキストファイルの内容ソース HTML(「テンプレートの編集」で作ります)
C6: 保存する際のファイルタイプtext/html

「PDF 生成」工程(DocRaptor: PDF 生成)

この工程は、データ項目「HTML File」の HTML ファイルを DocRaptor に送り、生成された PDF ファイルをデータ項目「PDF File」に保存します。DocRaptor の API にアクセスするための HTTP 認証設定を、先に登録します。

「PDF 生成」工程の設定画面で、「C1: API キーをユーザ名に設定した BASIC 認証設定」の[設定はこちらから]をクリックして、「HTTP 認証設定」の画面を開きます。上部のタブで[Basic 認証]を開き、「アプリ固有の設定」の[追加]をクリックします。「名前」に任意の名前(例: 「DocRaptor」)、「ユーザ名」に DocRaptor の API キーを入力し、「パスワード」は空のまま[保存]をクリックします。

サンプルアプリで設定する内容は次のとおりです。

設定項目サンプルアプリでの設定
C1: API キーをユーザ名に設定した BASIC 認証設定登録した HTTP 認証設定の名前(例: 「DocRaptor」)
C2: 変換元の HTML が保存されているデータ項目「HTML File」
C3: 生成された PDF ファイルを保存するデータ項目「PDF File」
C5: 保存する際のファイル名#{processInstanceId}.pdf(拡張子は .pdf にします)

登録した名前が「C1: API キーをユーザ名に設定した BASIC 認証設定」の選択肢に表示されない場合は、設定画面を再読み込みしてください。

テンプレートの編集

テンプレート(invoice.A4.html)を書き換えてソース HTML を作ります。一部を書き換えるたびに PDF を生成して確かめながら進めます。PDF を生成する手順は「[DocRaptor: PDF 生成]の実行」で説明します。

テンプレートの確認

まず、テンプレートをそのまま PDF にします。「PDF 生成」工程の設定画面で[この工程のみデバッグ]をクリックします。開始されたデバッグケースの「テストデータを入力」工程で、データ項目「HTML File」に invoice.A4.html を直接[追加]して、[「テストデータを入力」処理完了]をクリックします。デバッグケースが終了したら、データ項目「PDF File」の PDF ファイルを開きます。

生成された PDF の社名やメールアドレスには、仮の文字列が入っています。下の図の緑色の枠で囲んだ部分は、どの請求書にも共通する固定の文字列で、日本語の文言や自社の社名に書き換えます。赤色の枠で囲んだ部分は請求ごとに変わる文字列で、データ項目の値が挿し込まれるように SpEL 式に書き換えます。

固定文字列を書き換える

invoice.A4.html をテキストエディタで開きます。コードの前半は、レイアウトを指定するスタイルシート(<style>〜</style>)です。PDF に表示される文字は <header> 以降にあります。まず「Logo & Name」「Invoice #100」の箇所を書き換えます。

    <div class="logoAndName">
      <svg>
        <circle cx="50%" cy="50%" r="40%" stroke="black" stroke-width="3" fill="black" />
      </svg>
      <h1>Logo & Name</h1>
    </div>
    <!-- Details about the invoice are on the right top side of each page. -->
    <div class="invoiceDetails">
      <h2>Invoice #100</h2>
      <p>
        07 March 2021
      </p>
    </div>

<h1>Logo & Name</h1> を社名(Questetra)に、<h2>Invoice #100</h2> を「請求書番号:#100」に書き換え、<p>07 March 2021</p> の日付の前に「発行日:」を足します。ロゴマークを表示する <svg>〜</svg> は削除します。

    <div class="logoAndName">
      <h1>Questetra</h1>
    </div>
    <!-- Details about the invoice are on the right top side of each page. -->
    <div class="invoiceDetails">
      <h2>請求書番号:#100</h2>
      <p>
        発行日:07 March 2021
      </p>
    </div>

書き換えたら、コード全体を「HTML ファイル生成」工程の「C4: テキストファイルの内容」に貼り付け、「[DocRaptor: PDF 生成]の実行」の手順で PDF を確認します。以降も、一部を書き換えるたびに同じように確認します。

SpEL 式への書き換え

次に、請求ごとに変わる部分を、データ項目を参照する SpEL 式に書き換えます。データ項目の値は #{#フィールド名} で参照します。文字のデータ項目は、#{#escaper.escapeHtml(#フィールド名)} のように HTML エスケープしてから挿し込みます。エスケープしておくと、入力に < や & が含まれていても HTML の構造が崩れません。「固定文字列の書き換え」で書き換えたコードでは、「#100」は「請求書番号」(q_invoice_id)、「07 March 2021」は「請求書発行日」(q_issue_date)を参照する式にします。

    <div class="logoAndName">
      <h1>Questetra</h1>
    </div>
    <!-- Details about the invoice are on the right top side of each page. -->
    <div class="invoiceDetails">
      <h2>請求書番号:#{#escaper.escapeHtml(#q_invoice_id)}</h2>
      <p>
        発行日:#{#q_issue_date}
      </p>
    </div>

関数を使うと、出力の形式を変えられます。次のコードは、テンプレートの見出し「Invoice to」「Due Date」を「ご請求先」「お支払期限」に書き換え、請求先と支払期限のデータ項目を挿し込む例です。「請求先住所」(文字 (複数行))と「支払期限」(日付 (年月日))は、関数で出力の形式を変えています。

    <div>
      <h3>ご請求先</h3>
      <p>
        <b>#{#escaper.escapeHtml(#q_billing_name)}</b>
        <br />
        #{#joiner.splitJoin(#escaper.escapeHtml(#q_billing_address), '<br>')}
        <br />
        <a href="mailto:#{#escaper.escapeHtml(#q_billing_email)}">
          #{#escaper.escapeHtml(#q_billing_email)}
        </a>
      </p>
    </div>
    <!-- Additional details can be placed below the invoice details. -->
    <div>
      <h3>お支払期限</h3>
      <p>
        <b>#{#dateFormatter.format('yyyy年MM月dd日', #q_due_date)}</b>
      </p>

文字型複数行に入力された値をそのまま #{#q_billing_address} とすると、HTML では改行されず1行で表示されてしまいます。行ごとに<br> を挿入する関数を記述して複数行を保ちます。

[DocRaptor: PDF 生成]の実行

生成された PDF

開始イベントから[デバッグ実行]して「データ入力」工程を処理すると、「HTML ファイル生成」工程と「PDF 生成」工程が続けて実行されます。終了したデバッグケースの詳細画面で、データ項目「PDF File」の PDF ファイルを開きます。デバッグ実行なので、PDF は DocRaptor の TEST モードで生成されます(「DocRaptor での準備」を参照)。

テンプレート全体を書き換えたら、「データ入力」工程で入力した値が PDF ファイルに挿し込まれていることを確認します。期待どおりの PDF にならない場合は、「HTML ファイル生成」工程の「C4: テキストファイルの内容」のソース HTML を見直してください。

HTML コードサンプル

テンプレート(invoice.A4.html)を書き換えたソース HTML の全文です(クリックして開く)。

HTML コード(全文)
<!--
The following is the license for the original template file.
------------------------------------
MIT License

Copyright (c) 2021 Expected Behavior, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------
-->
<style>
/* 
Import the desired font from Google fonts. 
*/
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&display=swap');

/* 
Define all colors used in this template 
*/
:root{
  --font-color: black;
  --highlight-color: #60D0E4;
  --header-bg-color: #B8E6F1;
  --footer-bg-color: #BFC0C3;
  --table-row-separator-color: #BFC0C3;
}

@page{
  /*
  This CSS highlights how page sizes, margins, and margin boxes are set.
  https://docraptor.com/documentation/article/1067959-size-dimensions-orientation

  Within the page margin boxes content from running elements is used instead of a 
  standard content string. The name which is passed in the element() function can
  be found in the CSS code below in a position property and is defined there by 
  the running() function.
  */
  size:A4;
  margin:8cm 0 3cm 0;

  @top-left{
  	content:element(header);
  }

  @bottom-left{
  	content:element(footer);
  }
}

/* 
The body itself has no margin but a padding top & bottom 1cm and left & right 2cm.
Additionally the default font family, size and color for the document is defined
here.
*/
body{
  margin:0;
  padding:1cm 2cm;
  color:var(--font-color);
  font-family: 'Montserrat', sans-serif;
  font-size:10pt;
}

/*
The links in the document should not be highlighted by an different color and underline
instead we use the color value inherit to get the current texts color.
*/
a{
  color:inherit;
  text-decoration:none;
}

/*
For the dividers in the document we use an HR element with a margin top and bottom 
of 1cm, no height and only a border top of one millimeter.
*/
hr{
  margin:1cm 0;
  height:0;
  border:0;
  border-top:1mm solid var(--highlight-color);
}

/*
The page header in our document uses the HTML HEADER element, we define a height 
of 8cm matching the margin top of the page (see @page rule) and a padding left
and right of 2cm. We did not give the page itself a margin of 2cm to ensure that
the background color goes to the edges of the document.

As mentioned above in the comment for the @page the position property with the 
value running(header) makes this HTML element float into the top left page margin
box. This page margin box repeats on every page in case we would have a multi-page
invoice.
*/
header{
  height:8cm;
  padding:0 2cm;
  position:running(header);
  background-color:var(--header-bg-color);
}

/*
For the different sections in the header we use some flexbox and keep space between
with the justify-content property.
*/
header .headerSection{
  display:flex;
  justify-content:space-between;
}

/*
To move the first sections a little down and have more space between the top of 
the document and the logo/company name we give the section a padding top of 5mm.
*/
header .headerSection:first-child{
  padding-top:.5cm;
}

/*
Similar we keep some space at the bottom of the header with the padding-bottom
property.
*/
header .headerSection:last-child{
  padding-bottom:.5cm;
}

/*
Within the header sections we have defined two DIV elements, and the last one in
each headerSection element should only take 35% of the headers width.
*/
header .headerSection div:last-child{
  width:35%;
}

/*
For the logo, where we use an SVG image and the company text we also use flexbox
to align them correctly.
*/
header .logoAndName{
  display:flex;
  align-items:center;
  justify-content:space-between;
}

/*
The SVG gets set to a fixed size and get 5mm margin right to keep some distance
to the company name.
*/
header .logoAndName svg{
  width:1.5cm;
  height:1.5cm;
  margin-right:.5cm;
}

/*
To ensure the top right section "Invoice #100" starts on the same level as the Logo &
Name we set a padding top of 1cm for this element.
*/
header .headerSection .invoiceDetails{
  padding-top:.5cm;
}

/*
The H3 element "ISSUED TO" gets another 25mm margin to the right to keep some 
space between this header and the client's address.
Additionally this header text gets the hightlight color as font color.
*/
header .headerSection h3{
  margin:0 .75cm 0 0;
  color:var(--highlight-color);
}

/*
Put some margin between the "DUE DATE" and "AMOUNT" headings.
*/
header .headerSection div:last-of-type h3:last-of-type{
  margin-top:.5cm;
}

/*
The paragraphs within the header sections DIV elements get a small 2px margin top
to ensure its in line with the "ISSUED TO" header text.
*/
header .headerSection div p{
  margin-top:2px;
}

/*
All header elements and paragraphs within the HTML HEADER tag get a margin of 0.
*/
header h1,
header h2,
header h3,
header p{
  margin:0;
}

/*
The invoice details should not be uppercase and also be aligned to the right.
*/
header .invoiceDetails,
header .invoiceDetails h2{
  text-align:right;
  font-size:1em;
  text-transform:none;
}

/*
Heading of level 2 and 3 ("DUE DATE", "AMOUNT" and "INVOICE TO") need to be written in 
uppercase, so we use the text-transform property for that.
*/
header h2,
header h3{
  text-transform:uppercase;
}

/*
The divider in the HEADER element gets a slightly different margin than the 
standard dividers.
*/
header hr{
  margin:1cm 0 .5cm 0;
}

/*
Our main content is all within the HTML MAIN element. In this template this are
two tables. The one which lists all items and the table which shows us the 
subtotal, tax and total amount.

Both tables get the full width and collapse the border.
*/
main table{
  width:100%;
  border-collapse:collapse;
}

/*
We put the first tables headers in a THEAD element, this way they repeat on the
next page if our table overflows to multiple pages.

The text color gets set to the highlight color.
*/
main table thead th{
  height:1cm;
  color:var(--highlight-color);
}

/*
For the last three columns we set a fixed width of 2.5cm, so if we would change
the documents size only the first column with the item name and description grows.
*/
main table thead th:nth-of-type(2),
main table thead th:nth-of-type(3),
main table thead th:last-of-type{
  width:2.5cm;
}

/*
The items itself are all with the TBODY element, each cell gets a padding top
and bottom of 2mm.
*/
main table tbody td{
  padding:2mm 0;
}

/*
The cells in the last column (in this template the column containing the total)
get a text align right so the text is at the end of the table.
*/
main table thead th:last-of-type,
main table tbody td:last-of-type{
  text-align:right;
}

/*
By default text within TH elements is aligned in the center, we do not want that
so we overwrite it with an left alignment.
*/
main table th{
  text-align:left;
}

/*
The summary table, so the table containing the subtotal, tax and total amount 
gets a width of 40% + 2cm. The plus 2cm is added because our body has a 2cm padding
but we want our highlight color for the total row to go to the edge of the document.

To move the table to the right side we simply set a margin-left of 60%.
*/
main table.summary{
  width:calc(40% + 2cm);
  margin-left:60%;
  margin-top:.5cm;
}

/*
The row containing the total amount gets its background color set to the highlight 
color and the font weight to bold.
*/
main table.summary tr.total{
  font-weight:bold;
  background-color:var(--highlight-color);
}

/*
The TH elements of the summary table are not on top but the cells on the left side
these get a padding left of 1cm to give the highlight color some space.
*/
main table.summary th{
  padding:4mm 0 4mm 1cm;
}

/*
As only the highlight background color should go to the edge of the document
but the text should still have the 2cm distance, we set the padding right to 
2cm.
*/
main table.summary td{
  padding:4mm 2cm 4mm 0;
  border-bottom:0;
}

/*
The content below the tables is placed in a ASIDE element next to the MAIN element.
To ensure this element is always at the bottom of the page, just above the page 
footer, we use the Prince custom property "-prince-float" with the value bottom.

See Page Floats on https://www.princexml.com/howcome/2021/guides/float/.
*/
aside{
  -prince-float: bottom;
  padding:0 2cm .5cm 2cm;
}

/*
The content itself is shown in 2 columns we use flexbox for this.
*/
aside > div{
  display:flex;
  justify-content:space-between;
}

/*
Each "column" has a width of 45% of the document.
*/
aside > div > div{
  width:45%;
}

/*
The list with the payment options has no bullet points and no margin.
*/
aside > div > div ul{
  list-style-type:none;
  margin:0;
}

/*
The page footer in our document uses the HTML FOOTER element, we define a height 
of 3cm matching the margin bottom of the page (see @page rule) and a padding left
and right of 2cm. We did not give the page itself a margin of 2cm to ensure that
the background color goes to the edges of the document.

As mentioned above in the comment for the @page the position property with the 
value running(footer) makes this HTML element float into the bottom left page margin
box. This page margin box repeats on every page in case we would have a multi-page
invoice.

The content inside the footer is aligned with the help of line-height 3cm and a 
flexbox for the child elements.
*/
footer{
  height:3cm;
  line-height:3cm;
  padding:0 2cm;
  position:running(footer);
  background-color:var(--footer-bg-color);
  font-size:8pt;
  display:flex;
  align-items:baseline;
  justify-content:space-between;
}

/*
The first link in the footer, which points to the company website is highlighted 
in bold.
*/
footer a:first-child{
  font-weight:bold;
}

</style>
<!-- The header element will appear on the top of each page of this invoice document. -->
<header>
  <div class="headerSection">
    <!-- As a logo we take an SVG element and add the name in an standard H1 element behind it. -->
    <div class="logoAndName">
      <h1>Questetra</h1>
    </div>
    <!-- Details about the invoice are on the right top side of each page. -->
    <div class="invoiceDetails">
      <h2>請求書番号:#{#escaper.escapeHtml(#q_invoice_id)}</h2>
      <p>
        発行日:#{#q_issue_date}
      </p>
    </div>
  </div>
  <!-- The two header rows are divided by an blue line, we use the HR element for this. -->
  <hr />
  <div class="headerSection">
    <!-- The clients details come on the left side below the logo and company name. -->
    <div>
      <h3>ご請求先</h3>
      <p>
        <b>#{#escaper.escapeHtml(#q_billing_name)}</b>
        <br />
        #{#joiner.splitJoin(#escaper.escapeHtml(#q_billing_address), '<br>')}
        <br />
        <a href="mailto:#{#escaper.escapeHtml(#q_billing_email)}">
          #{#escaper.escapeHtml(#q_billing_email)}
        </a>
      </p>
    </div>
    <!-- Additional details can be placed below the invoice details. -->
    <div>
      <h3>お支払期限</h3>
      <p>
        <b>#{#dateFormatter.format('yyyy年MM月dd日', #q_due_date)}</b>
      </p>
      <h3>ご請求金額</h3>
      <p>
        <b>#{#q_total}円</b>
      </p>
    </div>
  </div>
</header>

<!-- The footer contains the company's website and address. To align the address details we will use flexbox in the CSS style. -->
<footer>
    <a href="https://questetra.com">
      questetra.com
    </a>
    <a href="mailto:customer-sevice@questetra.com">
      customer-sevice@questetra.com
    </a>
    <span>
      京都市中京区 御池通間之町東入高宮町206<br>御池ビル4階 604-0835
    </span>
</footer>

<!-- In the main section the table for the separate items is added. Also we add another table for the summary, so subtotal, tax and total amount. -->
<main>
  <table>
    <!-- A THEAD element is used to ensure the header of the table is repeated if it consumes more than one page. -->
    <thead>
      <tr>
        <th>商品名</th>
        <th>単価</th>
        <th>数量</th>
        <th>価格</th>
      </tr>
    </thead>
    <!-- The single invoice items are all within the TBODY of the table. -->
    <tbody>
      <tr>
        <td>
          <b>#{#escaper.escapeHtml(#q_item_name1)}</b>
          <br />
          #{#escaper.escapeHtml(#q_remark1)}
        </td>
        <td>
          #{#q_unit1}
        </td>
        <td>
          #{#q_quantity1}
        </td>
        <td>
          #{#q_price1}
        </td>
      </tr>
      <tr>
        <td>
          <b>#{#escaper.escapeHtml(#q_item_name2)}</b>
          <br />
          #{#escaper.escapeHtml(#q_remark2)}
        </td>
        <td>
          #{#q_unit2}
        </td>
        <td>
          #{#q_quantity2}
        </td>
        <td>
          #{#q_price2}
        </td>
      </tr>
      <tr>
        <td>
          <b>#{#escaper.escapeHtml(#q_item_name3)}</b>
          <br />
          #{#escaper.escapeHtml(#q_remark3)}
        </td>
        <td>
          #{#q_unit3}
        </td>
        <td>
          #{#q_quantity3}
        </td>
        <td>
          #{#q_price3}
        </td>
      </tr>
    </tbody>
  </table>
  <!-- The summary table contains the subtotal, tax and total amount. -->
  <table class="summary">
    <tr>
      <th>
        小計
      </th>
      <td>
        #{#q_subtotal}
      </td>
    </tr>
    <tr>
      <th>
        消費税
      </th>
      <td>
        #{#q_tax}
      </td>
    </tr>
    <tr class="total">
      <th>
        合計
      </th>
      <td>
        #{#q_total}
      </td>
    </tr>
  </table>
</main>
<!-- Within the aside tag we will put the terms and conditions which shall be shown below the invoice table. -->
<aside>
  <!-- Before the terms and conditions we will add another blue divider line with the help of the HR tag. -->
  <hr />
  <div>
    <div>
      <b>手数料について</b>
      <p>
        お振込手数料は御社ご負担にてお願い致します。
      </p>
    </div>
    <div>
      <b>お振込先</b>
      <ul>
        <li>○○銀行 ○○支店 普通 000000000</li>
        <li>名義:カ)クエステトラ</li>
      </ul>
    </div>
  </div>
</aside>

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む