Java.lang.OutOfMemoryError с использованием библиотеки PdfBox в Java при наличии большого PDF-файла с большим количествоApache

Ответить
Anonymous
 Java.lang.OutOfMemoryError с использованием библиотеки PdfBox в Java при наличии большого PDF-файла с большим количество

Сообщение Anonymous »

Я использую Apache pdfBox для создания PDF-файла, содержащего огромное количество ссылок. PDF-документ должен содержать большую таблицу (1 млн строк), некоторые столбцы таблицы могут иметь тип ссылки.
Я заметил, что когда я не использую ссылки, у меня есть разумное использование памяти (пара сотен МБ).
При использовании ссылок даже 3 ГБ оперативной памяти недостаточно
Есть ли способ использовать меньше памяти?
Ниже вы найдете модульный тест для воспроизведения

Код: Выделить всё

`import java.io.IOException;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.junit.Test;

public class TestTable {

@Test public void main1() throws IOException {
try (PDDocument document = new PDDocument(MemoryUsageSetting.setupTempFileOnly())) {
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
float margin = 40;
float yStart = page.getMediaBox().getHeight() - margin;
float tableWidth = page.getMediaBox().getWidth() - 2 * margin;
float yPosition = yStart;
int rows = 1000000;
float rowHeight = 20f;
float cellMargin = 5f;
float[] columnWidths = {50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f, 50f};
int cols = columnWidths.length;

drawTableHeader(contentStream, margin, yPosition, tableWidth, rowHeight, cellMargin, columnWidths);

for (int i = 0; i < rows; i++) {
if (isPageFull(page, yPosition)) {
contentStream.close();
yPosition = yStart;
page = new PDPage(PDRectangle.A4);
document.addPage(page);
contentStream = new PDPageContentStream(document, page);
drawTableHeader(contentStream, margin, yPosition, tableWidth, rowHeight, cellMargin, columnWidths);
}

yPosition -= rowHeight;
drawTableRow(contentStream, margin, yPosition, tableWidth, rowHeight, cellMargin, columnWidths, page);

}
contentStream.close();
document.save("tableBOX.pdf");
} catch (IOException e) {
e.printStackTrace();
}
}

private static void drawTableHeader(PDPageContentStream contentStream, float xStart, float yStart, float tableWidth, float rowHeight, float cellMargin, float[] columnWidths) throws IOException {
contentStream.setNonStrokingColor(150, 150, 150);
contentStream.addRect(xStart, yStart, tableWidth, rowHeight);
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);

// Set the text color to black
contentStream.setNonStrokingColor(0, 0, 0);

float yPosition = yStart + (rowHeight / 2);
for (int i = 0; i < columnWidths.length; i++) {
String headerText = "Column " + (i + 1);
float width = columnWidths[i];
float xPosition = xStart + (width / 2) - (headerText.length() / 2 * 4);
contentStream.beginText();
contentStream.newLineAtOffset(xPosition, yPosition);
contentStream.showText(headerText);
contentStream.endText();

xStart += width;
}
}

private static void drawTableRow(PDPageContentStream pDPageContentStream, float xStart, float yStart, float tableWidth, float rowHeight, float cellMargin, float[] columnWidths, PDPage page) throws IOException {
pDPageContentStream.setNonStrokingColor(255, 255, 255);
pDPageContentStream.addRect(xStart, yStart, tableWidth, rowHeight);
pDPageContentStream.setFont(PDType1Font.TIMES_ROMAN, cellMargin);
pDPageContentStream.setNonStrokingColor(0, 0, 0);

float yPosition = yStart + (rowHeight / 2);
for (int i = 0; i < columnWidths.length; i++) {
String cellText = "Row "  + (i + 1);
float width = columnWidths[i];
float xPosition = xStart + cellMargin;

if (i % 2 == 0) {
PDAnnotationLink txtLink = new PDAnnotationLink();
PDRectangle position = new PDRectangle(xPosition, yPosition, 50, 20);
PDActionURI action = new PDActionURI();
action.setURI("www.google.com");
txtLink.setAction(action);
txtLink.setRectangle(position);
page.getAnnotations().add(txtLink); // issue with annotations loaded in memory most probably

} else {
pDPageContentStream.beginText();
pDPageContentStream.newLineAtOffset(xPosition, yPosition);
pDPageContentStream.showText(cellText);
pDPageContentStream.endText();
}
xStart += width;
}
}

private static boolean isPageFull(PDPage page, float yPosition) throws IOException {
float threshold = 700;
float remainingSpace = page.getMediaBox().getHeight() - yPosition;
return remainingSpace > threshold;
}
}`

Я знаю, что проблема на этом уровне: page.getAnnotations().add(txtLink);
Я хочу продолжать использовать ссылки, но с меньшим объемом памяти есть ли способ добиться этого?

Подробнее здесь: https://stackoverflow.com/questions/783 ... rge-pdf-wi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Apache»