我修改了TextToPDF类以检测内容文件中的某些标记。 找到代码中心时,文本居中。
无法正常工作,X坐标似乎不受尊重
当我显示x:coordonate时,我得到: 0
0
18.861816
2.9138184
238.31181
9.933823
68.68582
10.347824
40.14981
在生成的pdf中,第6行应该在第5行之前开始,但是从第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 如您所见,文本未正确居中。
答案 0 :(得分: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
参数,然后从新x值中减去此前xPosition
值。
答案 1 :(得分:0)
也许您正在尝试将所有文本块插入到彼此中。
您在循环中调用contentStream.begintText()
,但在整个循环之外只调用contentStream.endText()
一次。
我不熟悉TextToPDF
,只是一个猜测。但在我看来,下一个缩进是正确的,它只相对于前一个块,呈现,因为prevoius块没有正确关闭。
我建议将beginText()
与endText()
s配对,这会有所帮助。