web-dev-qa-db-ja.com

pdfboxラップテキスト

私は次のコードでPDFBoxを使用しています:

doc = new PDDocument();
page = new PDPage();

doc.addPage(page);
PDFont font = PDType1Font.COURIER;

pdftitle = new PDPageContentStream(doc, page);
pdftitle.beginText();
pdftitle.setFont( font, 12 );
pdftitle.moveTextPositionByAmount( 40, 740 );
pdftitle.drawString("Here I insert a lot of text");
pdftitle.endText();
pdftitle.close();

自動的に別の行に移動するようにテキストを折り返す方法を知っている人はいますか?

15
Igor Tupitsyn

テキストを自動的に折り返すことはできないと思います。ただし、テキストを自分で折り返すことはできます。 PDFBox drawStringを使用して改行を挿入する方法 および PDFboxを使用して固定幅の段落を作成するにはどうすればよいですか? を参照してください。

4
Lukas

これは私のために働いた。 WordUtilsとsplitの組み合わせ

String[] wrT = null;
String s = null;
text = "Job Description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque hendrerit lectus nec ipsum gravida placerat. Fusce eu erat orci. Nunc eget augue neque. Fusce arcu risus, pulvinar eu blandit ac, congue non tellus. Sed eu neque vitae dui placerat ultricies vel vitae mi. Vivamus vulputate nullam.";
wrT = WordUtils.wrap(text, 100).split("\\r?\\n");

for (int i=0; i< wrT.length; i++) {
    contents.beginText();
    contents.setFont(PDType1Font.HELVETICA, 10);
    contents.newLineAtOffset(50,600-i*15);
    s = wrT[i];
    contents.showText(s);
    contents.endText(); 
}
7

PdfBoxとBoxableはどちらも、セル幅よりも長いテキストの部分を自動的に折り返します。つまり、セル幅= 80文幅= 100の場合、幅20のテキストの残りの部分は次の行から始まります(注:幅について説明しました) (文によって消費される実際のスペース)長さ(文字数)ではありません)

文の幅= 60の場合、セルの幅を埋めるために幅20のテキストが必要になり、それ以降のテキストは次の行に移動します解決策:この幅20をスペースで埋めます

セルの塗りつぶされていないスペース= cellWidth-sentenceWidth、numberOfSpaces =セルの埋められていないスペース/単一のスペースの幅

    private String autoWrappedHeaderText(String text, float cellWidth) {
    List<String> splitStrings = Arrays.asList(text.split("\n"));
    String wholeString = "";
    for (String sentence : splitStrings) {
        float sentenceWidth = FontUtils.getStringWidth(headerCellTemplate.getFont(), " " + sentence + " ",
                headerCellTemplate.getFontSize());
        if (sentenceWidth < cellWidth) {
            float spaceWidth = FontUtils.getStringWidth(headerCellTemplate.getFont(), " ",
                    headerCellTemplate.getFontSize());
            int numberOfSpacesReq = (int) ((cellWidth - sentenceWidth) / spaceWidth);
            wholeString += sentence;
            for (int counter = 0; counter < numberOfSpacesReq; counter++) {
                wholeString += " ";
            }
        }
    }

    return wholeString;
}
cell = headerRow.createCell(cellWidth * 100 / table.getWidth(), headerText, HorizontalAlignment.LEFT, VerticalAlignment.TOP);
0
Rishav

PdfBOXで改行問題の解決策を見つけました

一般に、テキストを折り返すには3つの手順が必要です。

1)ラップする必要のある文字列で各単語を分割し、文字列の配列に配置します。文字列[]パーツ

2)(textlength /(1行の文字数))を使用して文字列バッファの配列を作成します。例: 280/70 = 5 >> 5つの改行が必要です!

3)1行の最大文字数の制限が許可されるまで、パーツをstringbuffer [i]に入れます。

4)stringbuffer.length <改行になるまでループします

メソッドsplitStringはそれを行うメソッドです。メソッドwriteTextは、ラップされたテキストをPDFに描画するだけです。

これが例です

import Java.io.IOException;
import Java.util.ArrayList;

import org.Apache.pdfbox.exceptions.COSVisitorException;
import org.Apache.pdfbox.pdmodel.PDDocument;
import org.Apache.pdfbox.pdmodel.PDPage;
import org.Apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.Apache.pdfbox.pdmodel.font.PDFont;
import org.Apache.pdfbox.pdmodel.font.PDType1Font;

public class pdfTest{
 private ArrayList<String> arrayList;
 private PDDocument document;
 private PDFont font = PDType1Font.HELVETICA;

 pdfTest(PDDocument document, ArrayList arrayList, PDFont font) throws COSVisitorException, IOException {
    this.document = document;
    this.arrayList = arrayList;
    this.font = font;   
    writeText(document, arrayList, 30, 750, font); //method for easily drawing a text into a pdf
 } //constructor


 public void writeText(PDDocument document, ArrayList arrayList, int positionX, int positionY, PDFont font) throws IOException, COSVisitorException {
     PDPage page = new PDPage();
     document.addPage( page );

     // Start a new content stream
     PDPageContentStream contentStream = new PDPageContentStream(document, page);

     // Define a text content stream using the selected font, moving the cursor and drawing the text in arrayList
     for(int i=0;i<arrayList.size();i++) {  
         String text=(String) arrayList.get(i);
         String [] tmpText = splitString(text);
         for( int k=0;k<tmpText.length;k++) {
             contentStream.beginText();
             contentStream.setFont(font, 12);
             contentStream.moveTextPositionByAmount(positionX, positionY);
             contentStream.drawString(tmpText[k]);           
             contentStream.endText();
             positionY=positionY-20;
         }           
         contentStream.setLineWidth((float) 0.25);
     }

     // Make sure that the content stream is closed:
     contentStream.close();      
     document.save( "Test.pdf");
     document.close();
 } //main

 public static void main(String[] args) throws COSVisitorException, IOException {
     ArrayList arrayList = new ArrayList<String>();

     PDDocument document = new PDDocument();
     PDFont font = PDType1Font.HELVETICA;
     PDPage page = new PDPage();

     arrayList.add(       "12345 56789 0 aaa bbbew wel kwäer kweork merkweporkm roer wer wer e  er"
                        + "df sdmfkl  slkdfm sdkfdof sopdkfp osdkfo sädölf söldm,f sdkfpoekr re, ä"
                        + " sdfk msdlkfmsdlk fsdlkfnsdlk fnlkdn flksdnfkl sdnlkfn kln df sdmfn sn END");
     arrayList.add("this is an example");
     arrayList.add("Java pdfbox stackoverflow");         

     new pdfTest(document,arrayList,font);
     System.out.println("pdf created!");
 }

 public String [] splitString(String text) {
     /* pdfBox doesnt support linebreaks. Therefore, following steps are requierd to automatically put linebreaks in the pdf
      * 1) split each Word in string that has to be linefeded and put them into an array of string, e.g. String [] parts
      * 2) create an array of stringbuffer with (textlength/(number of characters in a line)), e.g. 280/70=5 >> we need 5 linebreaks!
      * 3) put the parts into the stringbuffer[i], until the limit of maximum number of characters in a line is allowed,
      * 4) loop until stringbuffer.length < linebreaks
      * 
      */
     int linebreaks=text.length()/80; //how many linebreaks do I need?  
     String [] newText = new String[linebreaks+1];       
     String tmpText = text;
     String [] parts = tmpText.split(" "); //save each Word into an array-element

     //split each Word in String into a an array of String text. 
     StringBuffer [] stringBuffer = new StringBuffer[linebreaks+1]; //StringBuffer is necessary because of manipulating text
     int i=0; //initialize counter 
     int totalTextLength=0;
     for(int k=0; k<linebreaks+1;k++) {
         stringBuffer[k] = new StringBuffer();
         while(true) {               
             if (i>=parts.length) break; //avoid NullPointerException
             totalTextLength=totalTextLength+parts[i].length(); //count each Word in String              
             if (totalTextLength>80) break; //put each Word in a stringbuffer until string length is >80
             stringBuffer[k].append(parts[i]);
             stringBuffer[k].append(" ");
             i++;
         }
         //reset counter, save linebreaked text into the array, finally convert it to a string 
         totalTextLength=0; 
         newText[k] = stringBuffer[k].toString();
     }
     return newText;
 } 

} 
0
Ramses