Выпуск PDF при достижении конца страницы

1

Ну, у меня возникают проблемы при создании новых страниц.

Я получаю данные из запроса.

Извините, если я размещаю много кода, но все это необходимо, и я не уверен, как сделать MCVE, поскольку я довольно новичок в работе с PDF.

Эта проблема:

Перед записью следующего блока кода проверить текущий Y коорд, я могу добиться этого, но когда мне нужно создать новую страницу и начать писать снова, а случается это

Вот коды, используемые в 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;
    }

Этот метод делает то же самое, что и в первом, но используется как, я знаю, я не должен и не должен использовать жестко заданные значения, например 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++;
}

Любая помощь, руководство, была бы очень оценена и заблаговременно

  • 0
    Ваш renderSubscriptionNew перебирает dataList , и три или один такой элемент списка располагаются рядом друг с другом. Таким образом, в случае, когда три элемента данных расположены рядом друг с другом, вы не должны переключать страницы во время вызова rtext а должны уже проверить тройку данных в renderSubscriptionNew и переключить страницу только один раз ( перед вызовом rtext для первой записи тройной). Боюсь, ваш код требует некоторой очистки.
  • 0
    @mkl, так что, если я хорошо понял, что вы говорите, я должен удалить все checkContentStream в rText, но для значения я прав? Таким образом, он будет проверять мои координаты Y один раз в строке, а для значений он будет проверять, поэтому в больших текстах он всегда будет разрывать страницу.
Показать ещё 4 комментария
Теги:
pdf
pdf-generation
rendering
pdfbox

1 ответ

2
Лучший ответ

Благодаря @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;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню