1

我修改了 TextToPDF 类来检测内容文件中的一些标签。当找到标签中心时,文本居中。

这不能正常工作,X 坐标似乎不受尊重

当我显示 x:坐标时,我得到: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

生成文件的结果 在此处输入图像描述

此字符串被放入 StringReader 中,用于 createPDFFromText 参数。

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 节“文本定位运算符”)

因此,您必须记住xPosition使用的值和

  • 要么就在这条线之后

    contentStream.drawString( nextLineToDraw.toString() );
    

    插入

    contentStream.moveTextPositionByAmount( -xPosition, 0 );
    

    如果线居中;

  • 或者等到确定moveTextPositionByAmount下一行文本的参数,xPosition然后从新的 x 值中减去这个以前的值。

于 2013-03-30T07:28:04.937 回答
0

也许您正试图将所有文本块相互插入。

您在循环中调用contentStream.begintText(),但contentStream.endText()在整个循环之外只调用一次。

我不熟悉TextToPDF,只是猜测。但在我看来,下一个缩进是正确的,它只是相对于前一个块渲染,因为前一个块没有正确关闭。

我建议将beginText()s 与endText()s 配对,这会有所帮助。

于 2013-03-29T12:18:08.613 回答