1

コンテンツ ファイル内のタグを検出するように TextToPDF クラスを変更しました。タグの中心が見つかると、テキストが中央に配置されます。

それは正しく機能しません。X 座標が尊重されていないようです

x: coordonate を表示すると、次のようになります: 0

0

18.861816

2.9138184

238.31181

9.933823

68.68582

10.347824

40.14981

生成された pdf では、6 行目は 5 行目の前に開始されるはずですが、後に開始されます。

238.31181 > 9.933823 しかし、pdfbox は 9.933823 > 238.31181 と言っているようです

生成されたファイルの結果 ここに画像の説明を入力

この文字列は、createPDFFromText パラメーターの StringReader に入れられます。

String rawText = "Children's heart surgery has been suspended with immediate effect at a hospital which is embroiled in a long-running row over the future of paediatric cardiac services in England. \n "
    + "#CENTER#The decision to stop congenital heart surgery at Leeds General Infirmary comes just a day after the High Court quashed plans by the NHS to close its children's unit after ruling the consultation process was flawed.\n "
    + "It follows concerns raised about patients' care including allegations the hospital was avoiding referring children for complex and life-saving treatment at another centre in Newcastle.\n "
    + "Leeds Teaching Hospitals NHS Trust said the temporary measure was being taken to allow an internal review to be conducted following consultation with the Care Quality Commission (CQC).";

コード

public PDDocument createPDFFromText( Reader text ) throws IOException
{
    PDDocument doc = null;
    PDSimpleFont font = PDType1Font.TIMES_ROMAN;
    int fontSize = 12;
    boolean isCentered = false;
    try
    {

        final int margin = 40;
        float height = font.getFontDescriptor().getFontBoundingBox().getHeight()/1000;

        //calculate font height and increase by 5 percent.
        height = height*fontSize*1.05f;
        doc = new PDDocument();
        BufferedReader data = new BufferedReader( text );
        String nextLine = null;
        PDPage page = new PDPage();
        PDPageContentStream contentStream = null;
        float y = -1;
        float maxStringLength = page.getMediaBox().getWidth() - 2*margin;

        // There is a special case of creating a PDF document from an empty string.
        boolean textIsEmpty = true;

        while( (nextLine = data.readLine()) != null )
        {

            // The input text is nonEmpty. New pages will be created and added
            // to the PDF document as they are needed, depending on the length of
            // the text.
            textIsEmpty = false;

            String[] lineWords = nextLine.trim().split( " " );
            int lineIndex = 0;
            while( lineIndex < lineWords.length )
            {
                StringBuffer nextLineToDraw = new StringBuffer();
                float lengthIfUsingNextWord = 0;
                do
                {
                    nextLineToDraw.append( lineWords[lineIndex] );
                    nextLineToDraw.append( " " );
                    lineIndex++;
                    if( lineIndex < lineWords.length )
                    {
                        String lineWithNextWord = nextLineToDraw.toString() + lineWords[lineIndex];
                        lengthIfUsingNextWord =
                            (font.getStringWidth( lineWithNextWord )/1000) * fontSize;
                    }
                }
                while( lineIndex < lineWords.length &&
                       lengthIfUsingNextWord < maxStringLength );
                if( y < margin )
                {
                    // We have crossed the end-of-page boundary and need to extend the
                    // document by another page.
                    page = new PDPage();
                    doc.addPage( page );
                    if( contentStream != null )
                    {
                        contentStream.endText();
                        contentStream.close();
                    }
                    contentStream = new PDPageContentStream(doc, page);
                    contentStream.setFont( font, fontSize );
                    contentStream.beginText();
                    y = page.getMediaBox().getHeight() - margin + height;
                    contentStream.moveTextPositionByAmount(
                        margin, y );

                }
                //System.out.println( "Drawing string at " + x + "," + y );

                if( contentStream == null )
                {
                    throw new IOException( "Error:Expected non-null content stream." );
                }

                String txt = nextLineToDraw.toString();

                if ( txt.indexOf( "#CENTER#" ) != -1 || isCentered )
                {
                    txt = nextLineToDraw.toString().replaceAll( "#CENTER#", "" );

                    PDRectangle pageSize = page.findMediaBox();
                    float stringWidth = font.getStringWidth( txt );
                    float xPosition = ( pageSize.getWidth() - ( 2 * margin ) - ( stringWidth * fontSize ) / 1000f ) / 2f;

                    System.out.println( xPosition );

                    contentStream.moveTextPositionByAmount( xPosition, -height );
                    isCentered = true;
                }
                else
                {
                                            System.out.println( 0);
                    contentStream.moveTextPositionByAmount( 0, -height );
                }

                y -= height;
                contentStream.drawString( nextLineToDraw.toString() );
            }
        }
        if (textIsEmpty)
        {
            doc.addPage(page);
        }

        if( contentStream != null )
        {
            contentStream.endText();
            contentStream.close();
        }
    }
    catch( IOException io )
    {
        if( doc != null )
        {
            doc.close();
        }
        throw io;
    }
    return doc;
}

ファイルの結果はこちらから入手できます: http://filebin.ca/br6slMSfOR6/testUnitairePdf.pdfご覧のとおり 、テキストは正しく中央揃えされていません。

4

2 に答える 2

2

問題は(@GaborSchが彼の回答へのコメントで推測したように)

contentStream.moveTextPositionByAmount()

一定のマージンに対してではなく、最後の行に対して相対的に機能します。

詳細に:

PDPageContentStreamメソッドは次のmoveTextPositionByAmountように文書化されています。

/**
 * The Td operator.
 * @param x The x coordinate.
 * @param y The y coordinate.
 * @throws IOException If there is an error writing to the stream.
 */
public void moveTextPositionByAmount( float x, float y ) throws IOException

Td演算子は、次のように文書化されています。

tx ty Td現在の行の先頭から (tx, ty) だけオフセットした次の行の先頭に移動します。tx および ty は、スケーリングされていないテキスト スペース単位で表される数値を示すものとします。より正確には、この演算子は次の割り当てを実行します。

ここに画像の説明を入力

(PDF 仕様ISO 32000-1:2008、セクション 9.4.2 "Text-Positioning Operators" を参照)

xPositionしたがって、使用する値を覚えておく必要があります。

  • 行の直後

    contentStream.drawString( nextLineToDraw.toString() );
    

    入れる

    contentStream.moveTextPositionByAmount( -xPosition, 0 );
    

    行が中央に配置されている場合。

  • moveTextPositionByAmountまたは、テキストの次の行の引数を決定するまで待ってxPositionから、新しい x 値からこの前の値を減算します。

于 2013-03-30T07:28:04.937 に答える
0

すべてのテキスト ブロックを互いに挿入しようとしている可能性があります。

ループ内で呼び出しますが、ループ全体の外で 1 回だけcontentStream.begintText()呼び出します。contentStream.endText()

私はよく知らないTextToPDF、ただの推測です。しかし、次のインデントは正しいと思われます。前のブロックが適切に閉じられていないため、前のブロックに対して相対的にレンダリングされるだけです。

beginText()s とsをペアにすることをお勧めしendText()ます。

于 2013-03-29T12:18:08.613 に答える