Java 动态创建新页面时出现PDFBox问题

Java 动态创建新页面时出现PDFBox问题,java,pdfbox,Java,Pdfbox,考虑一个SQL查询,其结果将写入pdf 我可以成功地将内容(从查询中检索)写入pdf,但如果内容超过一页的最大限制,它会截断内容。这意味着,只创建一个页面 在写入pdf(通过PDFBox)时,如何知道我们已经到达页面的末尾,以便触发doc.addPage(页面)一旦我们动态地知道我们已经到达页面的终点 以下是代码: public PDDocument processPdf(Class1 objectClass1) { String text; int count; //N

考虑一个SQL查询,其结果将写入pdf

我可以成功地将内容(从查询中检索)写入pdf,但如果内容超过一页的最大限制,它会截断内容。这意味着,只创建一个页面

在写入pdf(通过PDFBox)时,如何知道我们已经到达页面的末尾,以便触发
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坐标,将它设置为
    startYif(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);
     }