PDFを作成するためiTextを利用しています。そうしたPDFで、1行に2つの`String`を追加しなければなりません。  
1つ目の`String`(`string1`)の長さは1から10の間です。2つ目の`String`(`string2`)の長さは不明ですが、`string1`と`string2`の長さを合わせて10文字を超過しないようにしたいです。  
このような文字列を、下線が引かれた1行に追加するにはどうしたらいいですか？
CC BY-SA 4.0
2019-07-09T07:37:43.853
56512
2019-07-09T07:43:52.177
30882
question
java pdf
1行の文字数を制限するにはどうしたらいいですか？
[UnderlineParagraphWithTwoParts](https://github.com/sunrenjie/itext/blob/master/sandbox/src/main/java/sandbox/objects/UnderlineParagraphWithTwoParts.java)のサンプルコードを挙げたうえで、このサンプルコードがどのような問題を解決したのかをご説明したいと思います。

**第1の問題：**
1行を100文字に合わせたいです。まず、101文字を基準とします。`string1`と`string2`の間に空白が必要だと仮定したためです。(そうでない場合、サンプルコードを簡単に修正できる必要があります)

`string1`と`string2`の間の内容は事前に分からないので、すべてのグリフの幅が同一のフォントを選択しました。Courier(固定幅または等幅フォント)を使用します。プロポーショナルフォント(例：Arial)を使用したい場合は、`string1`と`string2`の組み合わせごとにフォントサイズを別途に計算しなければならないので、フォントサイズの計算が非常に困難で、各列のフォントサイズがすべて異なるおかしい見た目の文書になってしまいます。

このコードは、`COURIER`フォントの1文字の幅を基準にしてフォントサイズを計算します。ページの左右余白の間の使用可能な空間と同じ幅の1行に101文字を追加してみます。

```

    PdfFont font = PdfFontFactory.createFont(FontConstants.COURIER, PdfEncodings.WINANSI, false);
    float charWidth = font.getWidth(" ");
    int charactersPerLine = 101;
    float pageWidth = pdfDoc.getPage(1).getPageSize().getWidth() - doc.getLeftMargin() - doc.getRightMargin();
    float fontSize = (1000 * (pageWidth / (charWidth * charactersPerLine)));
    fontSize = ((int) (fontSize * 100)) / 100f;
    
```

ご参考までに、float値は四捨五入します。そうしないと、`float`値の使用に内在された丸め誤差により問題が発生することがあります。

**第2の問題：** 次に、1行に2つの文字列を追加してから下線を引きたいと思います。ご質問からは、このように文字列を整列したいのかは分かりかねます。

単純な作業としては、`string1`と`string2`を1つの空白で分離することがあります。

```

    public void addParagraphWithTwoParts2(Document doc, PdfFont font, String string1, String string2, float fontSize) {
     if (string1 == null) string1 = "";
     if (string1.length() > 10)
     string1 = string1.substring(0, 10);
     if (string2 == null) string2 = "";
     if (string1.length() + string2.length() > 100)
     string2 = string2.substring(0, 100 - string1.length());
     Paragraph p = new Paragraph(string1 + " " + string2).setFont(font).setFontSize(fontSize);
     doc.add(p);
     doc.add(new LineSeparator(new SolidLine(1)).setMarginTop(-6));
    }
    
```

より複雑な作業としては、`string2`を右側に整列させることがあります。

```

    ublic void addParagraphWithTwoParts1(Document doc, PdfFont font, String string1, String string2, float fontSize) {
     if (string1 == null) string1 = "";
     if (string1.length() > 10)
     string1 = string1.substring(0, 10);
     Text chunk1 = new Text(string1).setFont(font).setFontSize(fontSize);
     if (string2 == null) string2 = "";
     if (string1.length() + string2.length() > 100)
     string2 = string2.substring(0, 100 - string1.length());
     Text chunk2 = new Text(string2).setFont(font).setFontSize(fontSize);
     Paragraph p = new Paragraph();
     p.add(chunk1);
     p.addTabStops(new TabStop(1000, TabAlignment.RIGHT));
     p.add(new Tab());
     p.add(chunk2);
     doc.add(p);
     doc.add(new LineSeparator(new SolidLine(1)).setMarginTop(-6));
    }
    
```

ご覧のとおり、空白を追加する必要なく、`TabStop`のみを使用します。

```

    p.addTabStops(new TabStop(1000, TabAlignment.RIGHT));
    p.add(new Tab());
    
```

`string1`と`string2`が数字で構成されたサンプルコードを作成してみました。サンプルコードは以下のとおりです。

[![画像の説明をここに入力](https://i.stack.imgur.com/4Die0.png)](https://i.stack.imgur.com/4Die0.png)

スクリーンショットで`string2`が右側に整列されており、`string2`が`string1`のすぐ次に追加されたサンプルコード(ただし、空白1個により分離されている。)をご覧いただけます。
CC BY-SA 4.0
2019-07-09T07:43:52.177
56513
2019-07-09T07:43:52.177
30882
56512
answer