我可以插入这样的简单文字:
document = new PDDocument();
page = new PDPage(PDPage.PAGE_SIZE_A4);
document.addPage(page);
PDPageContentStream content = new PDPageContentStream(document, page);
content.beginText();
content.moveTextPositionByAmount (10 , 10);
content.drawString ("test text");
content.endText();
content.close();
但是如何使用width属性创建类似于HTML的段落?
<p style="width:200px;">test text</p>
答案 0 :(得分:23)
根据this answer,无法在某些文本中插入换行符并使PDF正确显示(无论是使用PDFBox还是其他内容),所以我认为自动换行某些文本以适应某些宽度也可能是不能自动完成的事情。 (此外,有很多方法可以包装文本 - 仅限整个单词,将它们分成小部分等)
This answer另一个问题(关于字符串居中)给出了一些关于如何自己做这个的指示。假设您编写了一个函数possibleWrapPoints(String):int[]
来列出文本中的所有点,可以发生自动换行(不包括“零”,包括“文本长度”),一种可能的解决方案可能是:
PDFont font = PDType1Font.HELVETICA_BOLD; // Or whatever font you want.
int fontSize = 16; // Or whatever font size you want.
int paragraphWidth = 200;
String text = "test text";
int start = 0;
int end = 0;
int height = 10;
for ( int i : possibleWrapPoints(text) ) {
float width = font.getStringWidth(text.substring(start,i)) / 1000 * fontSize;
if ( start < end && width > paragraphWidth ) {
// Draw partial text and increase height
content.moveTextPositionByAmount(10 , height);
content.drawString(text.substring(start,end));
height += font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
start = end;
}
end = i;
}
// Last piece of text
content.moveTextPositionByAmount(10 , height);
content.drawString(text.substring(start));
possibleWrapPoints
的一个示例,允许在任何不属于单词(reference)的点包装,可以是:
int[] possibleWrapPoints(String text) {
String[] split = text.split("(?<=\\W)");
int[] ret = new int[split.length];
ret[0] = split[0].length();
for ( int i = 1 ; i < split.length ; i++ )
ret[i] = ret[i-1] + split[i].length();
return ret;
}
更新:一些其他信息:
答案 1 :(得分:5)
我一直在努力将卢卡斯的回答与mgibsonbr结合起来并达成了这个目标。我认为,对于寻找开箱即用解决方案的人们更有帮助。
private void write(Paragraph paragraph) throws IOException {
out.beginText();
out.appendRawCommands(paragraph.getFontHeight() + " TL\n");
out.setFont(paragraph.getFont(), paragraph.getFontSize());
out.moveTextPositionByAmount(paragraph.getX(), paragraph.getY());
out.setStrokingColor(paragraph.getColor());
List<String> lines = paragraph.getLines();
for (Iterator<String> i = lines.iterator(); i.hasNext(); ) {
out.drawString(i.next().trim());
if (i.hasNext()) {
out.appendRawCommands("T*\n");
}
}
out.endText();
}
public class Paragraph {
/** position X */
private float x;
/** position Y */
private float y;
/** width of this paragraph */
private int width = 500;
/** text to write */
private String text;
/** font to use */
private PDType1Font font = PDType1Font.HELVETICA;
/** font size to use */
private int fontSize = 10;
private int color = 0;
public Paragraph(float x, float y, String text) {
this.x = x;
this.y = y;
this.text = text;
}
/**
* Break the text in lines
* @return
*/
public List<String> getLines() throws IOException {
List<String> result = Lists.newArrayList();
String[] split = text.split("(?<=\\W)");
int[] possibleWrapPoints = new int[split.length];
possibleWrapPoints[0] = split[0].length();
for ( int i = 1 ; i < split.length ; i++ ) {
possibleWrapPoints[i] = possibleWrapPoints[i-1] + split[i].length();
}
int start = 0;
int end = 0;
for ( int i : possibleWrapPoints ) {
float width = font.getStringWidth(text.substring(start,i)) / 1000 * fontSize;
if ( start < end && width > this.width ) {
result.add(text.substring(start,end));
start = end;
}
end = i;
}
// Last piece of text
result.add(text.substring(start));
return result;
}
public float getFontHeight() {
return font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
}
public Paragraph withWidth(int width) {
this.width = width;
return this;
}
public Paragraph withFont(PDType1Font font, int fontSize) {
this.font = font;
this.fontSize = fontSize;
return this;
}
public Paragraph withColor(int color) {
this.color = color;
return this;
}
public int getColor() {
return color;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public int getWidth() {
return width;
}
public String getText() {
return text;
}
public PDType1Font getFont() {
return font;
}
public int getFontSize() {
return fontSize;
}
}