【问题标题】:PDF issue while reaching end of page到达页面末尾时出现 PDF 问题
【发布时间】:2014-05-11 13:33:35
【问题描述】:

我在创建新页面时遇到了一些麻烦。

我从查询中获取数据。

对不起,如果我发布了很多代码,但这些都是必需的,我不确定如何进行 MCVE,因为我对使用 PDF 还很陌生。

这个问题是:

在编写下一个代码块之前,我会检查当前的 Y 坐标,我可以做到这一点,但是当我需要创建新页面并再次开始编写时,会发生this

以下是 PDF 中使用的代码:

public float checkContentStream(float y) throws Exception {
    float newY = checkYCoord(y, 3, 10);
    if (newY == 700) {
        if (content != null) {
        content.close();
        }

        File file = new File(logoPath);
        PDJpeg logoImg = new PDJpeg(doc, new FileInputStream(file));
        PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
        doc.addPage(page);
        content = new PDPageContentStream(doc, page);
        content.drawImage(logoImg, 50, 720);
        rHeader();
    }
    return newY;
    }

此方法检查是否达到 BOTTOM MARGIN = 60

private float checkYCoord(float y, int lines, int space) {
    float newY = y;
    for (int i = 0; i < lines; i++) {
        if ((newY - space) <= BOTTOM_MARGIN) {
        newY = 700f;
        return newY;
        } else {
        newY = newY - space;
        }
    }
    return y;
    }

此方法与第 1 种方法相同,但两者都使用,我知道我不应该也不能使用硬编码值,例如 10 或 3。

public float checkContentStream(float y, int lines, int space) throws Exception {
    float newY = checkYCoord(y, lines, space);
    if (newY == 700) {
        if (content != null) {
        content.close();
        }
        File file = new File(logoPath);
        PDJpeg logoImg = new PDJpeg(doc, new FileInputStream(file));
        PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
        doc.addPage(page);
        content = new PDPageContentStream(doc, page);
        content.drawImage(logoImg, 50, 720);
        rHeader();
    }
}

public float rText(float x, float y, int space, String labelField, String value, int fieldSize) throws Exception {
    if(fieldSize == 1){
        return rText(x, y, space, labelField, value, FIELD_WIDTH, VALUE_WIDTH);
        }
    else{
        if(fieldSize == 2){
        return rText(x, y, space, labelField, value, FIELD_WIDTH, DESC_WIDTH);
        }
        else{
        return rText(x, y, space, labelField, value, FIELD_WIDTH, TEXT_WIDTH);
        }
    }
}

我几乎可以肯定错误来自这种方法:

public float rText(float x, float y, int space, String labelField, String value, int fieldWidth, int valueWidth) throws Exception {
    PDFont font = PDType1Font.TIMES_BOLD;
    content.setFont(font, 9);
    float y1 = 0f;
    float y2 = 0f;
    //y = y >= 700 ? 700 : checkContentStream(y, 3, 10);
    if (value == null) {
        //y = checkYCoord(y, 1, 10);
        return rText(labelField, fieldWidth, x, y - 19, space, font, false);
        }else {
        //y = checkYCoord(y, 3, 10);
        y1 = rText(labelField, fieldWidth, x, y - 20, space, font, false);
        font = PDType1Font.TIMES_ROMAN;
        content.setFont(font, 9);
        y = checkYCoord(y, 3, 10); // Comment / Uncoment this line
        y2 = rText(value, valueWidth, x + fieldWidth + 10, y - 20, space, font, true);
        if (y1 >= y2) {
        return y2;
        } else {
        return y1;
        }
    }
}

此方法绘制文本

private float rText(String text, int width, float x, float y, int space, PDFont font, boolean isValue) throws Exception {
    float newY = y;
    int rowHeight = 0;
    ArrayList<String> rowList = getRows(text, width, font);
    if(isValue){
        newY = checkContentStream(newY);
        newY = newY == 700 ? 680 : newY;
        for (String row : rowList) {
        if(rowHeight >= 10){
            newY = checkContentStream(newY - 10);
            newY = newY == 700 ? 680 : newY;
        }
        else{
            newY = checkContentStream(newY);
            newY = newY == 700 ? 680 : newY;
        }
        content.beginText();
        content.moveTextPositionByAmount(x, newY);
        content.drawString(row);
        content.endText();
        rowHeight = rowHeight + 10;
        }
    }
    else{
        newY = checkContentStream(newY, rowList.size(), space);
        newY = newY == 700 ? 680 : newY;
        for(String row : rowList){
        content.beginText();
        content.moveTextPositionByAmount(x, newY - rowHeight);
        content.drawString(row);
        content.endText();
        rowHeight = rowHeight + 10;
        }
        newY -= (rowHeight - 9);
    }
    return newY;
}

另一个类中的这个方法从查询中获取数据:

private float renderSubscriptionNew(PdfRenderingPC pdf, float y, SubscriptionNew sNew) throws Exception {
    DataResponse dr = dataSvc.buildResponse(folio, sNew, unitSvc);
    List<Data> dataList = dr.getDataList();

    int i = 0;
    int j = 0;
    float y2[] = new float[3];
    for (Data data : dataList) {
        String labelField = constants.getString(data.getName());
        String value = getValue(data);
        float xCoord = 0;
        boolean getNewRow = false;
        int fieldSize = 1;
        switch (i) {
        case 0:
        case 4:
        xCoord = LEFT_MARGIN;
        break;
        case 1:
        case 5:
        xCoord = MIDDLE_COL;
        break;
        case 2:
        case 6:
        xCoord = RIGHT_COL;
        getNewRow = true;
        break;
        case 3:
        xCoord = LEFT_MARGIN;
        getNewRow = true;
        break;
        }
        if (getNewRow) {
        if(j == 0){
            y = pdf.rText(xCoord, y, 10, labelField, value, fieldSize);
        }
        else{
            y = pdf.rText(xCoord, y, 10, labelField, value, fieldSize);
            float min = y;
            for(int k = (j - 1); k >= 0; k--){
            if(y2[k] < min){
                min = y2[k];
            }
            }
            y = min;
            j = 0;
        }   
        } else {
            y2[j] = pdf.rText(xCoord, y, 10, labelField, value, fieldSize);
            j++;
        }
        i++;
}

任何帮助、指导,将不胜感激,并在此先感谢

【问题讨论】:

  • 您的renderSubscriptionNew 迭代dataList,并且三个或一个这样的列表元素彼此相邻排列。因此,在三个数据元素彼此相邻的情况下,您不能在调用rtext 期间切换页面,而必须已经检查renderSubscriptionNew 中的数据三元组并且只为它切换一次页面(之前 调用rtext 作为三元组的第一个条目)。恐怕您的代码需要大量清理。
  • @mkl 所以如果我理解你在说什么,我应该删除 rText 上的所有 checkContentStream,但是为了价值,我说的对吗?这样,它将每行验证一次我的 Y 坐标,并且对于值它会检查,因此在较大的文本中它总是会分页。
  • 实际上我怀疑从 rtext 内部检查是否是一个好主意,我认为检查应该是代码知道是否有多个数据相邻的地方,即在 renderSubscriptionNew .也许你的想法就足够了,不过我不知道。
  • @mkl 谢谢,我用第一条评论解决了这个问题,我在“renderSubscriptionNew”上做了它,它只检查文本超过 2 行时,所以它会在文本更大的情况下创建新页面比起那个来说。我要删除这个帖子吗?因为它没有答案,只有 cmets?
  • 我要删除这篇文章吗? - 好吧,你可以自己回答,而不是删除它,发布你的新 renderSubscriptionNew 代码和简短的解释。

标签: java pdf pdf-generation rendering pdfbox


【解决方案1】:

感谢@mkl他的评论,我这样解决了:

我在“renderSubscriptionNew”上添加了以下代码

if(visible){
    if (getNewRow) {
        if(j == 0){
        y = pdf.checkContentStream(y, 3, 10);
        y = pdf.rText(xCoord, y, 10, labelField, value, 
                  fieldSize);
        }
        else{
        y = pdf.rText(xCoord, y, 10, labelField, value, 
                  fieldSize);
        float min = y;
        for(int k = (j - 1); k >= 0; k--){
            if(y2[k] < min){
            min = y2[k];
            }
        }
        y = min;
        j = 0;
        }

    } else {
        if(j == 0){
        y = pdf.checkContentStream(y, 3, 10);
        }
        y2[j] = pdf.rText(xCoord, y, 10, labelField, value, 
                  fieldSize);
        j++;
    }
    }
    i++;
}

这是rText(最后一个):

private float rText(String text, int width, float x, float y, int space,
        PDFont font, boolean isValue) throws Exception {
float newY = y;
int rowHeight = 0;
ArrayList<String> rowList = getRows(text, width, font);
if(isValue){
    for (String row : rowList) {
    if(rowHeight >= 10){
        newY = checkContentStream(newY - 10);
        newY = newY == 700 ? 680 : newY;
    }
    else{
    }
    content.beginText();
    content.moveTextPositionByAmount(x, newY);
    content.drawString(row);
    content.endText();
    rowHeight = rowHeight + 10;
    }
}
else{
    for(String row : rowList){
    content.beginText();
    content.moveTextPositionByAmount(x, newY - rowHeight);
    content.drawString(row);
    content.endText();
    rowHeight = rowHeight + 10;
    }
    newY -= (rowHeight - 9);
}
return newY;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 2019-12-02
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    相关资源
    最近更新 更多