Как рисовать графику в PDF с помощью iText? - PullRequest
4 голосов
/ 20 октября 2011

Я пытаюсь завершить пример, который рисует графику и записывает ее в 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();

Нужно ли делать что-то еще, чтобы добавить графику в документ, или мой синтаксис неверен?

Ответы [ 6 ]

6 голосов
/ 28 октября 2011

Я не эксперт в 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 (холст) имеет гораздо больше функций, например rectangle.

4 голосов
/ 20 октября 2011

Имеет ли Document doc = new Document(PageSize.A4); какое-то значение?

Я не знаю, нужно ли вам добавить Paragraph, например:

doc.add(new Paragraph(...));

Также мы используем doc.add(ImgRaw); длядобавить изображения.

3 голосов
/ 24 октября 2011

Вы пробовали операции рисования на объекте g2d, которые просто используют фигуры вместо текста?Это исключило бы возможность чего-то странного с выбором шрифта или чего-то подобного.

iText In Action В главе 12 есть именно то, что вы ищете - это действительно стоит поднять. Предварительный просмотр главы 12

3 голосов
/ 20 октября 2011

Мне кажется, проблема в том, что directcontent пишет напрямую в объект страницы. Таким образом, вы можете добавить фон или фоновые изображения. Попробуйте добавить новую страницу (doc.newPage()) перед записью в прямое содержание.

3 голосов
/ 20 октября 2011

Не вдаваясь слишком далеко в это, я думаю, что ваш общий подход в порядке. Я думаю, что здесь может происходить то, что источник Graphics2D отличается от источника PDF, поэтому, возможно, вам нужно изменить вызов drawString (), чтобы он использовал 0,0 в качестве местоположения ??

1 голос
/ 29 октября 2011

Я только что собрал следующий модульный тест для последней HEAD 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 нет страниц - вы можете опубликовать трассировку стека для полученного исключения?

Я не могупредставьте себе, что добавление абзаца к документу имеет какое-либо значение (это ошибка, о которой можно было бы позаботиться давным-давно)

...