病院の問診票などに!手書きするのが手間な用紙をWebサイト上で入力しそのまま印刷する方法!PDF保存もOK!【CSS・jQuary】

最近は、なにかと申請書などPDF形式でオンライン上からダウンロードすることが可能ですが、どうしても手書きしなくてはいけない用紙もまだまだたくさんあります。
例えば、病院の問診票なんかがそうではないでしょうか?
初めての病院、なんとか受付を済ませたけれど、かならず書かなくてはならないのが「問診票」です。
「問診票」を受付に提出してからじゃないと、診察室には呼ばれませんから、急いで書きたいけれど、色々思い出しながら書く内容も多いですので、その分手間も時間もかかります。

そんな「問診票」を、受診する前に準備して提出することができたら便利じゃないですか?

問診票のデモ画面を作ってみました!

実際に作ってみたでも画面はこちらからご覧いただけます↓↓

※Edge、Chrome、firefoxで動作します。(Safariは不可)
※実物の用紙と同じ見た目から入力することを想定しているので、レスポンシブには対応していません(カスタマイズ可能)

実際に印刷される用紙と同じ見た目の画面から入力してもらう

下の画像は、入力してもらう画面と、実際に印刷される用紙をPDF出力したものです。(PDFは画像に変換してあります。)
「印刷する」のボタンをクリックすると、そのままブラウザの印刷設定画面が立ち上がり、印刷プレビューが表示されます。

入力する画面
印刷される用紙

そのまま印刷することもできますし、そこからPDFに保存することもできます。なので、紙で提出だけでなく、メールやフォームに添付して送信してもらうこともできます。

実際に、弊社の案件で、請求書や明細書などの固定の様式を、Web上で入力し印刷する機能を実装することがありました。
問診票のデモ画面を例に、どのように印刷の設定を行なっているかを解説していきたいと思います。

通常のHTMLとCSSだけで印刷できないの?

入力する画面は通常のWebサイトなので、HTMLとCSS(ボタン動作については+jQuary)で作成することができます。

では、このまま印刷しちゃダメなの?と思う方もいらっしゃるかもしれません。
しかしながら、このまま印刷すると、「印刷する」ボタンも、画像ではトリミングで消していますが、サイトのheaderやfooter、左右の余白など、必要のない部分も一緒に印刷されてしまいます。
印刷したいのは、あくまでの「問診票」の用紙部分だけです。

そこで用意するのが、印刷用のCSSと、印刷時の動作を設定したjQuaryです。

印刷用のCSSは「@media print」で設定する

印刷用のCSSといっても、特別なCSSファイルを用意する必要はありません。
印刷の際の設定を「@media print」を使って、別途記述すればいいので、入力画面のスタイルを設定したCSSファイルに書き加えてもOKです。

この際の注意として、CSSをのリンクをHTMLに書く際に、

<link rel="stylesheet" href="../css/print.css" media="all">

のように、「media=”all”」を忘れずに入れましょう。もし、印刷専用のCSSならば「media=”print”」でもOKです。

印刷用のCSSの書き方

@media print {

  //ここの中に印刷用のスタイルを記述していく
  
}

例えば、印刷するときは非表示にしたい部分がある場合は、

@media print {
  //ここの中に印刷用のスタイルを記述していく
  
  .no_print{//このクラス名をつけたものは印刷するとき非表示になる。
    display: none !important;
  }
  
}

こうすることで、クラス名に「no_print」と入れておくだけで、Web画面上では見えるけど、印刷するときだけ非表示にすることができます。

また、Web画面上のCSSではpxなどを使ってwidthやpadding、borderを設定し、あたかもWeb画面上に入力用紙があるよう見せているだけなので、A4の用紙で印刷するためにそれぞれmmで設定する必要があります。

@media print {
//ここの中に印刷用のスタイルを記述していく
  .no_print {//印刷時非表示
    display: none !important;
  }

/*==↓↓追加部分↓↓==*/
  #content_wrap .print_outer {
    max-width: none;
   //A4たての場合(A4横の場合は 297mm)
    width: 210mm;
    height: auto;
    box-sizing: border-box;
  //印刷見切れを確保するために上下左右の余白を設定します。
  //横幅が印刷範囲に収まらないときや、切れてしまうときはここを調整するとたいて治ります。
    padding: 5mm 5mm;
    margin: 0 auto;
  }
  #content_wrap .print_page {
 //入力用紙が存在するように見せていたcss設定を解除しています。
    border: none;
    padding: 0;
    margin: 0;
    width: auto;
    height: auto;
    min-height: auto;
  }
}

また、「input」や「select」、「textarea」などを使って入力欄を作っていますので、印刷するときは枠線やブラウザごとのデフォルト装飾が表示されないようにしましょう。

@media print {
  //ここの中に印刷用のスタイルを記述していく
  .no_print{//印刷時非表示
    display: none !important;
  }
#content_wrap .print_outer {
    max-width: none;
   //A4たての場合(A4横の場合は 297mm)
    width: 210mm;
    height: auto;
    box-sizing: border-box;
    padding: 5mm 5mm;
    margin: 0 auto;
  }
  #content_wrap .print_page {
    border: none;
    padding: 0;
    margin: 0;
    width: auto;
    height: auto;
    min-height: auto;
  }

/*==↓↓追加部分↓↓==*/
  //入力欄外線を非表示
  input,
  select {
    border: none !important;
    border-radius: 0 !important;
    padding: 0;
  }
  //ブラウザ設定で表示されているデフォルト装飾等の非表示
    input,
  select {
    border: none !important;
    border-radius: 0 !important;
    padding: 0;
  }
  input[type=time], 
  input[type=date] {
    -webkit-appearance: none;
  }
  input[type=time]::-webkit-clear-button, 
  input[type=time]::-webkit-calendar-picker-indicator,
  input[type=date]::-webkit-clear-button, 
  input[type=date]::-webkit-calendar-picker-indicator {
    background: none;
    display: none;
  }
  input[type=time]::-webkit-search-cancel-button, 
  input[type=time]::-ms-clear, 
  input[type=date]::-webkit-search-cancel-button, 
  input[type=date]::-ms-clear {
    display: none;
  }
  input[type=number] {
    -moz-appearance: textfield;
  }
  input[type=number]::-webkit-outer-spin-button,
   input[type=number]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
  }
  textarea {
    -webkit-appearance: none;
    resize: none;
    border: none !important;
  }
}

この他にも、今回のデモ画面では入れていませんが、例えば印刷するページが複数ページに渡る場合、どこで改ページさせるかなどを設定するCSSがあるので、必要に応じて設定しましょう。
以下は、それぞれの設定例です。

//必ず改ページさせる
  section{
    page-break-after: always;
  }
//印刷時に途中改行を防ぐ
h1,p{
    break-inside: avoid;
  }
//途中改ページをOKにする
 table{
    break-inside: auto;
  }

印刷する時と、印刷した後の動作をjQuaryで設定する

CSSだけでは設定できない部分はjQuaryやJavaScriptを使って設定するしていきます。

例えば、今回はWordPressの固定ページに「問診票」を入力するページを作成しています。
サイトのheaderやfooterなどの共通パーツは他のページへの干渉を防ぐため、非表示用のクラス名は印刷する」ボタンを押したら付与して、印刷画面を閉じたら削除する、という動作をjQuaryで設定しています。
その他にも、「印刷する」ボタンを押したらブラウザデフォルトの印刷設定画面が開くのもjQuaryで設定してます。

また、閲覧するブラウザによってはinputの装飾がCSSだけでは消えない場合があるので、jQuaryでうまい具合になるよう設定しています。

ボタンを押したら印刷する

//「印刷する」ボタンを押したら
$(".print_btn").on('click', function () {
    //印刷設定詳細画面を表示させる
    window.print();
  });

印刷する時と印刷した後の動きの設定


  window.addEventListener("beforeprint", () => {

    //印刷する前(印刷設定画面表示時)の設定をここに書く
    
  });
  
  window.addEventListener("afterprint", () => {

    //印刷が終わった後の設定をここに書く

  });

上記の二つのコードを使って印刷時の動作を設定します。

印刷用iQuaryの例

//印刷用の設定
jQuery(function($){
  //「印刷する」ボタンを押したら
  $(".print_btn").on('click', function () {
    //印刷したくない部分に非表示用のクラス名を付与
    $("#header").addClass("no_print");
    $("#page_header").addClass("no_print");
    $("#footer_image").addClass("no_print");
    $("#footer_top").addClass("no_print");
    $("#footer_bottom").addClass("no_print");
     //印刷設定詳細画面を表示させる
    window.print();
  });

 // firefoxでは印刷時も日付のinput[type="date"]装飾が残ってしまうため
 //input[type="text"]に変更して
 //ついでに年月日表示に変更する。
  const dateItem = $('input[type="date"]');
  const dateFormatJa = $('input[name="input_day"]');
  
  window.addEventListener("beforeprint", () => {
 //印刷する前の設定
    dateItem.attr("type", "text");
    dateItem.each(function () {
      const printVal = $(this).val().replace(/-/g, "/");
      $(this).val(printVal);
    });
    if (dateFormatJa.length) {
      const dateFormatJaVal = dateFormatJa.val();
      const dfj = dateFormatJaVal.split("/");
      dateFormatJa.val(`${dfj[0]}年${dfj[1]}月${dfj[2]}日`);
    }
  });
  
  window.addEventListener("afterprint", () => {
 //印刷が終わった後の設定

    //変更したinputのタイプや表示を戻し、追加したクラス名を削除
    if (dateFormatJa.length) {
      const dateFormatJaVal = dateFormatJa.val();
      const dfj = dateFormatJaVal.split(/\D/);
      dateFormatJa.val(`${dfj[0]}-${dfj[1]}-${dfj[2]}`);
    }
    dateItem.each(function () {
      const printVal = $(this).val().replace(/\//g, "-");
      $(this).val(printVal);
    });
    dateItem.attr("type", "date");
    $("#header").removeClass("no_print");
    $("#page_header").removeClass("no_print");
    $("#footer_image").removeClass("no_print");
    $("#footer_top").removeClass("no_print");
    $("#footer_bottom").removeClass("no_print");
  });
});

その他の印刷用の設定について

例えば、複数ページにわたって印刷するときに、「印刷画面にだけ共通のヘッダータイトルを追加」したり、請求書+明細書を作成していた際にあったのが、明細書だけに「フッター部分に”○/○”というページ数を表示させる」など、jQuaryを使って設定できることはたくさんあります。
これに関しては長くなってしまうので、別のブログで改めて解説させていただきたいと思います。
※関連記事はこちら(現在準備中)

まとめ

今回は、病院で使用する「問診票」を例にデモ画面を作成してみましたが、例えば動物病院では初診時は受診するペットの情報などを問診票のようなものに記載することがあると思います。
私が実際体験したことですが、「うちの子は何年生まれだったかな?」「誕生日はこれであっているかな?」など結構悩みました。
また、私は髪質がちょっと特殊なので、初めて来店する美容院なら「自分の髪質」「髪の悩み」「どのようにしたいか」「相談したいこと」など、店員さんにその場で口から説明しずらいことを事前にお伝えできたらいいのにな、と思うこともしばしば。施術する美容師さんも、なかなかコミュニケーションをとってくれないお客様もいらっしゃるでしょうから、「事前アンケート表」のようなものをご用意して、それに基づいて客様にヒアリングを行えば、コミュ障なお客様も少し心を開きやすいのではないかなと思います。

お問合せ

弊社では、施設予約システム「G.Open Door」を開発した際に、今回ご紹介した「サイトから特定の用紙を入力し、印刷・PDF保存する機能」を作成しました。
ご要望に応じて、お問合せフォームに入力された内容を印刷用紙に出力したり、電子印のオンオフ機能など様々な機能を別途追加することも可能です。
施設予約システムにご興味のある方や、ご自身のホームページに印刷機能を付けたいという方がいらっしゃいましたら、下記のお問合せからお気軽にご相談ください。

    関連記事

    1. 15分でウェブショップ完成!無料&簡単なBASEを使ったウェブショップ…

    2. ブログなどの投稿記事で実際にWEBデザイナーがよく使用する HTML一…

    3. 【SEO対策】HTMLと仲良しなフロントエンドエンジニアが教える検索エ…

    4. 施設予約などで使える! javaScript(jQuery)で半永久的…

    5. ブログなどの投稿記事で実際にWEBデザイナーがよく使用する CSS一覧…

    6. まだClassic editor使っている方へ WordPressのブ…