入力文字列を表のセル内に収める方法について

359 views
Skip to first unread message

kc juse

unread,
Aug 29, 2022, 8:59:08 PM8/29/22
to RapidReportサポート QAフォーラム
お世話になっております。

入力文字列を表のセル内に収めるために、現在、以下の方法をとっていますが、
行の折り返し位置がうまく制御できず、表セル内からはみ出してしまう場合があります。
(「帳票を1ページ内に収めるのが望ましい」、「表セル内の文字は見やすさを考慮しデフォルトフォントサイズは大きめとするが、最大文字数を入力した場合はデフォルトサイズでは収まらない」という要望から動的にフォントサイズを変更しています)

 (参考)「改行して全体を表示」を有効にするとワード境界での折り返しとなる

---------------------------------------------------------------------------------------------------------------------------
・帳票(rrpt)の表セルのプロパティ設定で、「改行して全体を表示」にチェックを入れる。
・以下のような「renderContent()」メソッドを持つカスタマイザを定義する。
 表セルの「横幅」と「高さ」を基準として、フォントサイズを順次小さくし、
 収まれば、そのフォントサイズで決定する。
---------------------------------------------------------------------------------------------------------------------------

そこで、以下のような2案を考えたのですが、
いずれの場合も、所望の情報の取得または書き換えができません。
以下のような処理はできないでしょうか?
他に代案がありましたら教えていただけますでしょうか?


(案1)
・帳票(rrpt)の表セルのプロパティ設定で、「改行して全体を表示」にチェックを入れない。

「co.systembase.report.Report.fill()」の呼び出し前に、表セルの「横幅」、「高さ」を考慮して、フォントサイズを計算して、手動で改行コードを文字列に入れる。
→ 表セルの「横幅」、「高さ」を取得できない。
  フォントサイズの変更は、引数渡し、またはグローバル変数を用いれば、カスタマイザ(renderContent())の呼び出し時の設定も可能と思われる。

(案2)
・帳票(rrpt)の表セルのプロパティ設定で、「改行して全体を表示」にチェックを入れない。

カスタマイザ(renderContent())の呼び出し時に、表セルの「横幅」、「高さ」を考慮して、フォントサイズを計算して、手動で改行コードを文字列に入れる。
→ 改行コードを入れた文字列に書き換えられない。


以上、よろしくお願いいたします。

上田

RapidReport

unread,
Aug 29, 2022, 11:23:23 PM8/29/22
to RapidReportサポート QAフォーラム
伊藤です。

「改行して全体を表示」としているのに、
内容がはみ出してしまう場合がある、ということでしょうか。

具体的にどのような内容なのか、
提示していただくことはできますか?

2022年8月30日火曜日 9:59:08 UTC+9 cals...@i-juse.co.jp:

kc juse

unread,
Aug 30, 2022, 12:33:17 AM8/30/22
to RapidReportサポート QAフォーラム
はい、「改行して全体を表示」としているのに、内容がはみ出してしまう場合があります。

「FTYPE-XXXX.rrpt」の「.COL3」に対して、「入力値.txt」の値を入力して、
帳票(PDF)出力したものが、「帳票PDF出力.PNG」です。

1行目の値が、入力した値をすべて出力できていません。
現状、入力時の回避策として、3行目のように、末尾に空白を入れることで出力できています。

カスタマイザのrenderContent()メソッド内で、以下のようなフォントサイズ計算を
行い、フォントサイズを設定し直しています。

----------------------------------------------------------------------------------------------------------
  @Override
  public void renderContent(Content content, Evaluator evaluator,
      Region region, ElementDesigns elementDesigns) {
    List<ElementDesign> eDs = elementDesigns.stream().filter(x -> "multiline_shrink".equals(x.get("id"))).collect(Collectors.toList());

    for(ElementDesign e : eDs) {
      Region r = e.getRegion(region);

      // 式(exp)を評価して、表示するテキストを取得します。
      String text = (String)evaluator.evalTry((String)e.get("exp"));
      if (text != null) {
        float size = 10.5f;
        if (!e.child("font").isNull("size")){
          size = Float.parseFloat(e.child("font").get("size").toString());
        }

        // 行数を数えます。
        int lines = 1;    // 行数
        int count = 0;    // ループ回数
        float width = r.getWidth();    // フィールドの横幅(point)
        float height = r.getHeight();    // フィールドの縦幅(point)

        // 余白が設定されている場合考慮
        if (!e.isNull("margin")) {
          ElementDesign margin = e.child("margin");
          float left = margin.isNull("left") ? 0f : Float.parseFloat(margin.get("left").toString());
          float top = margin.isNull("top") ? 0f : Float.parseFloat(margin.get("top").toString());
          float right = margin.isNull("right") ? 0f : Float.parseFloat(margin.get("right").toString());
          float bottom = margin.isNull("bottom") ? 0f : Float.parseFloat(margin.get("bottom").toString());
          width -= left + right;
          height -= top + bottom;
        }

        // テキストが枠内に収まるまでフォントを縮小します。
        do {

          // 初回は縮小しない
          if(count > 0) {
            size -= 0.5f;    // 0.5ptフォントを縮小
            lines = 1;    // 行数を初期化
          }
          float length = 0f;    //  文字列の幅(point)
          for(int i = 0;i < text.length();i++) {
            length += calcLength(text.charAt(i));

            // 改行コードか、自動折り返しの位置まで来たら行数を加算
            if (text.charAt(i) == '\n' || size * ( length + 1.1f ) > width) {
              lines++;
              length = calcLength(text.charAt(i));
            }
          }
          count++;
        } while(size * lines > height);
        
        // フォントサイズとフォント名を設定します。
        e.child("font").put("size", size);
        e.child("font").put("name", "mincho");
      }
    }
  }
----------------------------------------------------------------------------------------------------------

以上、よろしくお願いいたします。

2022年8月30日火曜日 12:23:23 UTC+9 RapidReport:
FTYPE-XXXX.rrpt
入力値.txt
帳票PDF出力.PNG

RapidReport

unread,
Aug 30, 2022, 1:02:44 AM8/30/22
to RapidReportサポート QAフォーラム
情報提供ありがとうございます。

調査いたしますのでお時間をください。
今週中には何らかの回答をいたします。

2022年8月30日火曜日 13:33:17 UTC+9 cals...@i-juse.co.jp:

RapidReport

unread,
Sep 1, 2022, 9:50:34 PM9/1/22
to RapidReportサポート QAフォーラム
「改行して全体表示」と「縮小して全体表示」を組み合わせた上で
セルに収まる最大のフォントサイズを動的に計算したい、ということになるでしょうか。

すみませんが、改行を行いつつの適正なフォントサイズは、
現状のRapidReportの仕様ですと計算することが困難です。

試されているようにカスタマイザ(renderContent)での対応を行うのが最善の方法と思います。
ただ、繰り返しになりますが、完全に適正なフォントサイズは計算困難ですので、
多少は余白が発生するとしても、内容がはみ出すことはないような小さめのフォントサイズを
算出するようにrenderContentを実装して対応していただくようお願いします。

2022年8月30日火曜日 13:33:17 UTC+9 cals...@i-juse.co.jp:
はい、「改行して全体を表示」としているのに、内容がはみ出してしまう場合があります。

kc juse

unread,
Sep 1, 2022, 10:05:16 PM9/1/22
to RapidReportサポート QAフォーラム
回答いただきありがとうございました。

> 「改行して全体表示」と「縮小して全体表示」を組み合わせた上で
> セルに収まる最大のフォントサイズを動的に計算したい、ということになるでしょうか。

はい、行いたいことは上記のとおりです。

提示いただいた「renderContentの実装を更新して対応」する対応案の他、
以下の方法で対応することもできそうということが分かりました。
ただし、以下の方法は、単語の途中で改行されてしまうことがあるため、
その出力でよいか顧客と相談したいと思います。

---------------------------------------------------------------------------------------------------
・「Report.Compatibility._4_34_PdfWrapNoRule = true;」を設定する
・TextSplitterByDrawingWidthクラスのコンストラクタ内のsuper()の引数を「false」とする。
・レンダリングエンジンのjarの内、「TextSplitterByDrawingWidth」のクラスファイルのみ差し替える。

→ 上記を行えば、renderContentの実装は現状のままでセル内に収まる。

(上記を当該帳票のみとする、_4_34_PdfWrapNoRule 変数の設定値をsuperの引数にする等については内部で検討します。
 5.4のjarファイルを使用しているため、他のクラスファイルはそのままとする方針)
---------------------------------------------------------------------------------------------------

また、質問等させていただきたい場合は、新しい会話を投稿いたしますので、
本件は閉じていただいて構いません。

2022年9月2日金曜日 10:50:34 UTC+9 RapidReport:
Reply all
Reply to author
Forward
0 new messages