どんな複雑さでも安心!無料のVisualforceでPDF生成の悩みを解決!

1. SpecialPdfControllerコントローラーの設定

データを取得するために、ApexでSpecialPdfControllerを作成します。

2. PDFレンダリング設定

VisualforceページにrenderAs="PDF"属性を追加して、ページをPDF形式でレンダリングします。

3. 帳票のレイアウト

**横向きレイアウト(size: A4 landscape)**でデザインします。

4. 漢字の表示設定

漢字を正しく表示させるために、以下のようにフォントを指定します:font-family: 'Arial Unicode MS'

5. 改ページ設定

改ページの設定

page-break-before: always;:指定箇所で必ず改ページを行います。

page-break-inside: avoid;:1つのセクションがページをまたがないようにします。

6. テーブルのレイアウト調整

テーブルレイアウトを正確に制御するため、以下を使用します:

table-layout: fixed;:列幅を固定します。

7. 内容がページをまたがないようにする方法

テーブルやセクションが改ページで分割されないように、以下のCSSを使用します:page-break-inside: avoid;

8. 実際のレイアウトデザインのポイント

幅の調整:内容がページの枠を超えないように、列幅を適切に割り当てます。

文字の自動改行:CSSでword-wrap: break-word;やword-break: break-all;を指定します。

  1. <apex:page controller="SpecialPdfController" renderAs="pdf" contentType="text/html;charset=UTF-8" applyHtmlTag="false" applyBodyTag="false" standardStylesheets="false" showheader="false">
  2. <html>
  3. <head>
  4. <style>
  5. @page {
  6. /* size: A4; */
  7. size: A4 landscape;
  8. margin: 8mm 10mm 10mm 10mm;
  9. }
  10. body { font-family: Arial Unicode MS; font-size: 9pt;}
  11. font { font-family: Arial Unicode MS !important; }
  12. .pagebreak {
  13. page-break-before: always;
  14. }
  15. .pageinside {
  16. page-break-inside:avoid;
  17. }
  18. .table-layout{
  19. table-layout: fixed;
  20. }
  21. table{
  22. border-collapse: collapse;
  23. width: 100%;
  24. }
  25. table td,
  26. table th {
  27. border: 1px solid black;
  28. padding: 1.3mm 0 1.3mm 1mm;
  29. line-height: 120%;
  30. }
  31. </style>
  32. </head>
  33. <body>
  34. <apex:repeat value="{!DocumentOutput}" var="headInfo">
  35. <p class="{!IF(headInfo.IsPageFlip,'pagebreak','')}" style="font-size:0;">pagebreak</p>
  36. <table class="table-layout">
  37. <tr>
  38. <td class="bg head-label">帳票内容</td>
  39. <td class="head-value"><apex:outputText value="{!headInfo.ShortName}" escape="false"/></td>
  40. </tr>
  41. </table>
  42. </apex:repeat>
  43. </body>
  44. </html>
  45. </apex:page> 

列の内容が改行されない場合の対策

Apexコードで長いテキストを適切な位置で分割し、手動で改行を追加します。

  1. public String addLineBreaks(String input, Integer breakWidth) {
  2. String result = ''; // 結果を格納
  3. Integer currentWidth = 0; // 現在の行幅
  4.  
  5. // 全角2として倍数拡張
  6. breakWidth = breakWidth * 130;
  7. for (Integer i = 0; i < input.length(); i++) {
  8. String currentChar = input.substring(i, i + 1); // 現在の文字を取得
  9. // 各文字の幅を取得し、幅を追加
  10. currentWidth += getCharacterWidth(currentChar);
  11. // 結果に現在の文字を追加
  12. result += currentChar;
  13. // 行幅が指定幅を超えた場合、改行を追加し、行幅をリセット
  14. if (currentWidth >= breakWidth) {
  15. result += '<br />';
  16. currentWidth = 0;
  17. }
  18. }
  19. return result;
  20. }
  21. // 文字幅を格納する配列を定義
  22. private static final Map<String, Integer> CHAR_WIDTHS = new Map<String, Integer> {
  23. '0' => 76, '1' => 64, '2' => 76, '3' => 76, '4' => 76, '5' => 76, '6' => 76, '7' => 76, '8' => 76, '9' => 76,
  24. 'a' => 76, 'b' => 76, 'c' => 67, 'd' => 76, 'e' => 76, 'f' => 29, 'g' => 76, 'h' => 76, 'i' => 43, 'k' => 67,
  25. 'l' => 43, 'm' => 120, 'n' => 76, 'o' => 76, 'p' => 76, 'q' => 76, 'r' => 40, 's' => 67, 't' => 31, 'u' => 76,
  26. 'v' => 67, 'w' => 103, 'x' => 67, 'y' => 67, 'z' => 67,
  27. 'A' => 94, 'B' => 94, 'C' => 103, 'D' => 103, 'E' => 94, 'F' => 85, 'G' => 111, 'H' => 103, 'I' => 31,
  28. 'J' => 67, 'K' => 94, 'L' => 76, 'M' => 120, 'N' => 103, 'O' => 111, 'P' => 94, 'Q' => 111, 'R' => 103,
  29. 'S' => 94, 'T' => 85, 'U' => 103, 'V' => 94, 'W' => 138, 'X' => 94, 'Y' => 94, 'Z' => 85
  30. };
  31.  
  32. // 文字ごとの幅を取得するメソッド
  33. private Integer getCharacterWidth(String character) {
  34. Integer codePoint = character.codePointAt(0);
  35. Integer ratio = 0; // 半角に調整係数
  36.  
  37. // 全角文字の幅判定
  38. if (Blob.valueOf(character).size() > 1) {
  39. return 136; // 全角文字の幅は136
  40. }
  41.  
  42. // 文字がCHAR_WIDTHSに存在するか確認
  43. if (CHAR_WIDTHS.containsKey(character)) {
  44. return Integer.valueOf(CHAR_WIDTHS.get(character)) + ratio;
  45. }
  46.  
  47. return 53;
  48. }

コメント