#java #spring-mvc #pdf-generation #itext #graphics2d
#java #spring-mvc #генерация PDF #itext #graphics2d
Вопрос:
Я пытаюсь завершить пример, который рисует графику и записывает их в PDF, но я продолжаю получать ошибки, что в PDF-файле нет страниц. если я добавлю что-то простое с помощью document.add(), после открытия он работает нормально, я просто никогда не вижу графику. Вот мой код:
Document document = new Document();
PdfWriter writer = new PdfWriter();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition",
" attachment; filename="Design.pdf"");
writer = PdfWriter.getInstance(document, response.getOutputStream());
document.open();
PdfContentByte cb = writer.getDirectContent();
Graphics2D graphics2D = cb.createGraphics(36, 54);
graphics2D.drawString("Hello World", 36, 54);
graphics2D.dispose();
document.close();
Должен ли я сделать что-то еще, чтобы добавить графику в документ, или мой синтаксис неверен?
Комментарии:
1. Поэтому добавление пустого места или чего-либо еще в документ сначала перед добавлением графики исправило это для меня. Собираюсь отметить правильность Стикена, поскольку это может быть то, что он пытался мне сказать. Если кто-нибудь захочет объяснить это, я назначу награду.
Ответ №1:
Я не эксперт в iText, но на прошлой неделе я попытался нарисовать с его помощью несколько кругов. Итак, это то, что я заметил во время своих тестов:
Если вы рисуете графику, вы должны (или, скажем, я должен, когда я попробовал это) «обернуть» графические команды в раздел, начинающийся с saveState()
и заканчивающийся restoreState()
, а также мне нужно было вызвать fillStroke()
— если я не вызываю fillStroke()
, тогда ничего не было нарисовано.
Пример
private void circle(float x, float y, PdfWriter writer) {
PdfContentByte canvas = writer.getDirectContent();
canvas.saveState();
canvas.setColorStroke(GrayColor.BLACK);
canvas.setColorFill(GrayColor.BLACK);
canvas.circle(x, y, 2);
canvas.fillStroke();
canvas.restoreState();
}
@Test
public void testPossition() throws DocumentException, IOException {
OutputStream outputStream = FileUtil.openOutputStream("testPosition.pdf");
//this is my personal file util, but it does not anything more
//then creating a file and opening the file stream.
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
markPosition(100, 100, writer);
document.add(new Paragraph("Total: 595 x 842 -- 72pt (1 inch)"));
document.close();
outputStream.flush();
outputStream.close();
}
private void markPosition(float x, float y, PdfWriter writer)
throws DocumentException, IOException {
placeChunck("x: " x " y: " y, x, y, writer);
circle(x, y, writer);
}
private void placeChunck(String text, float x, float y, PdfWriter writer)
throws DocumentException, IOException {
PdfContentByte canvas = writer.getDirectContent();
BaseFont font = BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
canvas.saveState();
canvas.beginText();
canvas.moveText(x, y);
canvas.setFontAndSize(font, 9);
canvas.showText(text);
canvas.endText();
canvas.restoreState();
}
PdfContentByte
Например, But (canvas) имеет гораздо больше функций rectangle
.
Ответ №2:
Имеет ли Document doc = new Document(PageSize.A4);
какое-либо значение?
Я не знаю, нужно ли вам добавлять Paragraph
подобное:
doc.add(new Paragraph(...));
Также мы используем doc.add(ImgRaw);
для добавления изображений.
Комментарии:
1. Объекты Graphics2D не принимаются в doc.add() как строки или изображения. Попробовал формат страницы A4, но безуспешно.
2. Также попытался добавить объект Graphics2D в абзац, поскольку он принимает объекты, а затем добавить абзац в документ, но получил «Вставка недопустимого элемента: PdfGraphics2D не может быть приведен к элементу»
Ответ №3:
Не вдаваясь в подробности, я думаю, что ваш общий подход хорош. Я думаю, что здесь может произойти то, что источник Graphics2D отличается от источника PDF, поэтому, возможно, вам нужно изменить вызов на drawString(), чтобы он использовал 0,0 в качестве местоположения??
Комментарии:
1. Я пробовал это, но все та же ошибка (исключение java.io.IOException: в документе нет страниц). Как будто он ничего не пытается написать.
2. Также пробовал (0,54), поскольку я полагаю, что система координат PDF по оси y увеличивается, а graphics2d снижается, но результат тот же.
3. О — я недостаточно внимательно читал — Проблема с документом не связана с проблемой системы координат — извините за отвлечение.
4. iText корректирует систему координат для вас. Никаких проблем нет.
Ответ №4:
Я думаю, проблема в том, что directcontent записывает непосредственно в объект страницы. Таким образом, вы можете добавлять фоны или фоновые изображения. Попробуйте добавить новую страницу ( doc.newPage()
) перед записью в directcontent.
Комментарии:
1. Тот же результат; Я был уверен, что это, по крайней мере, откроет PDF с пустой страницей, но с той же ошибкой.
2. Вы пробовали смотреть на примеры в itextpdf.com/themes/keyword.php?id=56 ? Может быть, они могут вам помочь…
Ответ №5:
Вы пробовали операции рисования на объекте g2d, которые просто используют фигуры вместо текста? Это исключило бы возможность чего-то странного с выбором шрифта или что-то в этом роде.
В главе 12 iText в действии есть именно то, что вы ищете — это действительно стоит взять. Предварительный просмотр главы 12
Комментарии:
1. Я попробовал несколько простых прямоугольников и даже линий.
Ответ №6:
Я только что собрал следующий модульный тест для последней главы iText:
Document document = new Document();
PdfWriter writer = new PdfWriter();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
writer = PdfWriter.getInstance(document, baos);
document.open();
PdfContentByte cb = writer.getDirectContent();
Graphics2D graphics2D = cb.createGraphics(36, 54);
graphics2D.setColor(Color.black);
graphics2D.drawRect(0, 0, 18, 27);
Font font = new Font("Serif", Font.PLAIN, 10);
graphics2D.setFont(font);
graphics2D.drawString("Yo Adrienne", 0, 54);
graphics2D.dispose();
document.close();
TestResourceUtils.openBytesAsPdf(baos.toByteArray());
И это работает нормально — я получаю маленький черный прямоугольник в нижнем левом углу страницы плюс текст. Обратите внимание, что я указываю X = 0 для моего метода drawString (вы указывали 36, что приводит к отображению текста за пределами границ изображения). Обратите внимание также, что я явно указал шрифт — если я оставлю это, он все равно будет отображаться, но обычно отличная идея не доверять значениям по умолчанию для такого рода вещей. Наконец, я явно задаю цвет переднего плана — опять же, это не обязательно, но доверять значениям по умолчанию может быть страшно.
Итак, я должен сказать, что основной проблемой здесь было размещение текста при x = 36.
Ни в одном из моих тестов я не смог создать ошибку, в которой говорилось, что в PDF-файле нет страниц — можете ли вы опубликовать трассировку стека исключения, которое вы получаете?
Я не могу себе представить, что добавление абзаца в документ имеет какое-либо значение для этого (это ошибка, о которой давно бы позаботились)