Java 动态创建新页面时出现PDFBox问题
考虑一个SQL查询,其结果将写入pdf 我可以成功地将内容(从查询中检索)写入pdf,但如果内容超过一页的最大限制,它会截断内容。这意味着,只创建一个页面 在写入pdf(通过PDFBox)时,如何知道我们已经到达页面的末尾,以便触发Java 动态创建新页面时出现PDFBox问题,java,pdfbox,Java,Pdfbox,考虑一个SQL查询,其结果将写入pdf 我可以成功地将内容(从查询中检索)写入pdf,但如果内容超过一页的最大限制,它会截断内容。这意味着,只创建一个页面 在写入pdf(通过PDFBox)时,如何知道我们已经到达页面的末尾,以便触发doc.addPage(页面)一旦我们动态地知道我们已经到达页面的终点 以下是代码: public PDDocument processPdf(Class1 objectClass1) { String text; int count; //N
doc.addPage(页面)代码>一旦我们动态地知道我们已经到达页面的终点
以下是代码:
public PDDocument processPdf(Class1 objectClass1) {
String text;
int count;
//New Document is created
PDDocument doc = new PDDocument();
List<Class1Questions> objectClass1Questions;
Class2 objectClass2;
try {
float fontSize = 12;
float margin = 72;
float leading = 1.5f * fontSize;
PDFont font = PDType1Font.HELVETICA;
PDPage page = new PDPage();
page.setMediaBox(PDRectangle.A4);
PDRectangle pageSize = page.getMediaBox();
float startX = pageSize.getLowerLeftX() + margin;
float startY = pageSize.getUpperRightY() - margin;
//First page is added
doc.addPage(page);
List<String> lines;
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
contentStream.setFont(font, fontSize);
contentStream.beginText();
//The resultset gets collected and written in PDF.
text = objectClass1.getClass1Name();
lines = spacing(text, margin, font, pageSize);
contentStream.newLineAtOffset(startX, startY);
contentStream.showText("Class1: ");
for (String line : lines) {
contentStream.showText(line);
contentStream.newLineAtOffset(0, -leading);
}
List<Class1Version> versionList = objectClass1.getClass1Versions();
for (Class1Version version : versionList) {
String versionNum = Long.toString(version.getClass1VersionNumber());
contentStream.showText("Version: " + versionNum);
contentStream.newLineAtOffset(0, -leading);
objectClass1Questions = version.getClass1Questions();
count = 0;
for (Class1Questions objectClass1Question : objectClass1Questions) {
count++;
objectClass2 = objectClass1Question.getQuestion();
String question = objectClass2.getQuestionDesc();
lines = spacing(question, margin, font, pageSize);
contentStream.showText("Q" + count + ": ");
for (String line : lines) {
contentStream.showText(line);
contentStream.newLineAtOffset(0, -leading);
}
contentStream.newLineAtOffset(0, -leading);
}
}
contentStream.endText();
contentStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
public List<String> spacing (String text, float margin, PDFont font, PDRectangle pageSize) throws IOException {
int lastSpace = -1;
List<String> lines = new ArrayList<String>();
float fontSize = 25;
float width = pageSize.getWidth() - 2*margin;
while (text.length() > 0)
{
int spaceIndex = text.indexOf(' ', lastSpace + 1);
if (spaceIndex < 0)
spaceIndex = text.length();
String subString = text.substring(0, spaceIndex);
float size = fontSize * font.getStringWidth(subString) / 1000;
System.out.printf("'%s' - %f of %f\n", subString, size, width);
if (size > width)
{
if (lastSpace < 0)
lastSpace = spaceIndex;
subString = text.substring(0, lastSpace);
lines.add(subString);
text = text.substring(lastSpace).trim();
System.out.printf("'%s' is line\n", subString);
lastSpace = -1;
}
else if (spaceIndex == text.length())
{
lines.add(text);
System.out.printf("'%s' is line\n", text);
text = "";
}
else
{
lastSpace = spaceIndex;
}
}
return lines;
}
公共PDDocument processPdf(Class1 objectClass1){
字符串文本;
整数计数;
//创建新文档
PDDocument doc=新的PDDocument();
列出问题;
类别2对象类别2;
试一试{
浮点数=12;
浮动保证金=72;
浮动前导=1.5f*fontSize;
PDFont font=PDType1Font.HELVETICA;
PDPage page=新PDPage();
第页:setMediaBox(PDA.A4);
PDRectangle pageSize=page.getMediaBox();
float startX=pageSize.getLowerLeftX()+页边距;
float startY=pageSize.getUpperRightY()-边距;
//添加第一页
文件添加页(第页);
列出行;
PDPageContentStream contentStream=新的PDPageContentStream(文档,页面);
setFont(字体,字体大小);
contentStream.beginText();
//结果集以PDF格式收集和编写。
text=objectClass1.getClassName();
行=间距(文本、边距、字体、页面大小);
contentStream.newlineatofset(startX,startY);
showText(“Class1:”);
用于(字符串行:行){
contentStream.showText(行);
contentStream.newlineatofset(0,-前导);
}
List versionList=objectClass1.GetClassVersions();
对于(ClassVersion:versionList){
字符串versionNum=Long.toString(version.getClassVersionNumber());
showText(“版本:”+versionNum);
contentStream.newlineatofset(0,-前导);
objectClass1Questions=version.getClass1Questions();
计数=0;
for(ClassQuestions对象ClassQuestion:ObjectClassQuestions){
计数++;
objectClass2=ObjectClassQuestion.getQuestion();
字符串question=objectClass2.getQuestionDesc();
行=间距(问题、边距、字体、页面大小);
showText(“Q”+count+“:”);
用于(字符串行:行){
contentStream.showText(行);
contentStream.newlineatofset(0,-前导);
}
contentStream.newlineatofset(0,-前导);
}
}
contentStream.endText();
contentStream.close();
}捕获(IOE异常){
e、 printStackTrace();
}
退货单;
}
公共列表间距(字符串文本、浮动边距、PDFont字体、PDRectangle pageSize)引发IOException{
int lastSpace=-1;
列表行=新的ArrayList();
浮点数=25;
float width=pageSize.getWidth()-2*页边距;
while(text.length()>0)
{
int spaceIndex=text.indexOf(“”,lastSpace+1);
if(spaceIndex<0)
spaceIndex=text.length();
String subString=text.subString(0,spaceIndex);
float size=fontSize*font.getStringWidth(子字符串)/1000;
System.out.printf(“%s”-%f,共%f\n”,子字符串,大小,宽度);
如果(尺寸>宽度)
{
if(lastSpace<0)
lastSpace=spaceIndex;
subString=text.subString(0,lastSpace);
行。添加(子字符串);
text=text.substring(lastSpace.trim();
System.out.printf(“%s”是行\n”,子字符串);
lastSpace=-1;
}
else if(spaceIndex==text.length())
{
行。添加(文本);
System.out.printf(“%s”是第\n行,文本);
text=“”;
}
其他的
{
lastSpace=spaceIndex;
}
}
回流线;
}
声明totalHeight变量,将其设置为边距高度
float totalHeight = margin;
获取字体高度,如下所示:
float fontHeight = font.getFontDescriptor().getFontBoundingBox()
.getHeight()
/ 1000 * fontSize;
但它不会返回确切的高度,您可以使用它来获得更好的结果。
然后获得a4页面大小:
float a4Height= PDRectangle.A4.getHeight();
每次输入新行时,增加总高度,并检查它是否超过A4高度(考虑到边距高度)
totalHeight += fontHeight;
if(totalHeight+margin>=a4Height){
page = new PDPage();
doc.addPage(page);
totalHeight = margin;
}
我试图采用@AhmetRasitBekar给出的解决方案和@mkl评论中提到的解决方案
引入一个变量,在其中记录当前y坐标,
将其设置为startY。将变量视为<代码> YCORDATIA< /COL> > 。
计算字体高度
float fontHeight=font.getFontDescriptor().getFontBoundingBox().getHeight()/1000*fontSize代码>
每次将文本内容写入pdf文件时,变量
ycoordination
将减少fontHeight
contentStream.showText(行);
Y坐标-=高度代码>
每次添加新行时,ycordination
将减少
前导
contentStream.newlineatofset(0,-前导);
Ycoordina-=领先代码>
每次访问和更改yCordinate
时,都会有一个条件
语句是用来检查yCordinate我不明白为什么这是一个问题;你能写内容。所以你把它们放在Y位置。因为页面的顶部是高度,这意味着离底部越近,y值就越小;如果它用我现有的代码更新了帖子,你必须引入一个变量,在这个变量中你注意到当前的y坐标,将它设置为startY
if(yCordinate <= 10){
page = new PDPage(); //new page created
page.setMediaBox(PDRectangle.A4);
pageSize = page.getMediaBox();
startX = pageSize.getLowerLeftX() + margin; //Calculate the X and Y cordinate
startY = pageSize.getUpperRightY() - margin;
doc.addPage(page); //Add the page to the PDDocument
yCordinate = startY; //Reset the yCordinate with the new Y cordinate
contentStream.endText(); //End and Close the previous contentStream
contentStream.close();
contentStream = new PDPageContentStream(doc, page); //Create a new contentStream and use it further
contentStream.setFont(font, fontSize);
contentStream.beginText();
contentStream.newLineAtOffset(startX, startY);
}