Запись большого графического 2D-документа в несколько PDF-файлов

Есть ли способ разделить большой 2D-документ с графикой jgraph на несколько страниц в формате pdf с помощью itext. У меня есть большая блок-схема, созданная с использованием jgraph. Мне нужно написать эту блок-схему в формате PDF с несколькими страницами. Мне нужно убедиться, что высота каждой страницы pdf ограничена 5000. SO, если высота графического объекта превышает 5000, она охватывает несколько страниц в pdf. Есть ли способ, которым я могу прочитать графический объект в куске (до высоты 5000 в каждой итерации), продолжать записывать его на новую страницу PDF и повторять, пока я полностью не прочитаю объект. Любые входы/направления будут полезны.

Ниже то, что у меня есть до сих пор -

float imageIdealHeight = 5000;
float imageIdealWidth = 5000;
float imageActualWidth=0;
float imageActualHeight=0;
mxRectangle imageBounds = ((mxGraph) graph).getGraphBounds();
imageActualWidth= (float) imageBounds.getWidth();
imageActualHeight = (float) imageBounds.getHeight();

System.out.println("Actual Width = "+imageActualWidth);
System.out.println("Actual Height = "+imageActualHeight);

numPages = (int) Math.ceil(imageActualHeight/imageIdealHeight);

Rectangle actualRectangle = new Rectangle(imageActualWidth, imageActualHeight);

//Custom Rectangle
Rectangle idealRectangle = new Rectangle(imageIdealWidth, imageIdealHeight);
Document document = new Document(idealRectangle );

//Create Pdf Writer
PdfWriter writer = PdfWriter.getInstance(document, fos);

//Open Document
document.open();

//Create huge template with actual image dimensions 
PdfContentByte canvas = writer.getDirectContent();
PdfTemplate template = canvas.createTemplate(imageActualWidth, imageActualHeight);
PdfCanvasFactory pdfCanvasFactory = new PdfCanvasFactory(canvas);

//Draw graphics to this template 
Graphics2D g2=template.createGraphics(imageActualWidth, imageActualHeight);
mxGraphics2DCanvas mxcanvas = new mxGraphics2DCanvas( g2);

mxcanvas = (mxGraphics2DCanvas) mxCellRenderer.drawCells((mxGraph) graph, null, 1, null, pdfCanvasFactory);
mxcanvas.getGraphics().dispose();

g2.dispose();

//Add template now...      
canvas.addTemplate(template,0, -15000);
document.newPage();
canvas.addTemplate(template, 0, -10000);
document.newPage();
canvas.addTemplate(template,0 , -5000);
document.newPage();
canvas.addTemplate(template, 0, 0);
document.newPage();

document.close();

person shoukatghouse    schedule 17.07.2014    source источник


Ответы (1)


Вам нужен PDF-файл со страницами размером 5000 на 5000 пользовательских единиц. Это означает, что вы собираетесь создать документ с таким прямоугольником:

Rectangle rect = new Rectangle(5000, 5000);
Document document = new Document(rect);

Очевидно, вы также собираетесь создать такой писатель:

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("my_file.pdf"));

И вы собираетесь открыть документ:

document.open();

Предположим, что ваше «изображение» Graphics2D имеет размер 10000 на 10000 точек. Это означает, что вам нужно будет распространить это изображение на 4 страницы.

Хитрость заключается в том, чтобы создать объект PdfTemplate размером 10000 на 10000.

PdfContentByte canvas = writer.getDirectContent();
PdfTemplate template = canvas.createTemplate(10000, 10000);

Теперь нарисуем графику к этому шаблону:

Graphics2D gd2d = new PdfGraphics2D(template, 10000, 10000);
// draw stuff to gd2d
gd2d.dispose();

Вы создали большой объект Form XObject с содержимым, которое не помещается на странице. Это содержимое будет присутствовать в файле PDF только один раз в виде внешнего объекта (отсюда и термин XObject). Все, что вам нужно сделать, это добавить документ столько раз, сколько необходимо.

Например:

canvas.addTemplate(template, 0, 0);
document.newPage();

Надеюсь, у вас есть представление о системе координат: (0, -5000), (-5000, -5000), (0, 0) и (-5000, 0) - это смещения x, y, необходимые для деления 10000 на 10000 объектов на 4 страницах размером всего 5000 на 5000.

Единственная оставшаяся строка кода:

document.close();

И вы сделали.

Полный пример см. в разделе LargeTemplate:

public void createPdf(String dest) throws IOException, DocumentException {
    float width = 602;
    float height = 15872;
    float maxHeight = 5000;
    Document document = new Document(new Rectangle(width, maxHeight));
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));
    document.open();
    PdfContentByte canvas = writer.getDirectContent();
    PdfTemplate template = canvas.createTemplate(width, height);
    Graphics2D g2d = new PdfGraphics2D(template, width, height);
    for (int x = 10; x < width; x += 100) {
        for (int y = 10; y < height; y += 100) {
            g2d.drawString(String.format("(%s,%s)", x, y), x, y);
        }
    }
    g2d.dispose();
    int pages = ((int)height / (int)maxHeight) + 1;
    for (int p = 0; p < pages; ) {
        p++;
        canvas.addTemplate(template, 0, (p * maxHeight) - height);
        document.newPage();
    }
    document.close();
}

Как видите, я использовал размеры, которые вы упомянули в своем комментарии:

float width = 602;
float height = 15872;

Я также ввожу максимальную высоту:

float maxHeight = 5000;

Я создаю страницу с размерами ширина x maxHeight и шаблон Graphics2D с размерами ширина x высота. В целях тестирования я использую drawString() для отображения информации о координатах через каждые 100 точек.

Я рассчитываю, сколько страниц мне понадобится:

int pages = ((int)height / (int)maxHeight) + 1;

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

for (int p = 0; p < pages; ) {
    p++;
    canvas.addTemplate(template, 0, (p * maxHeight) - height);
    document.newPage();
}

Я не знаю, какую математику вы используете, но итоговый PDF-файл выглядит именно так, как я ожидал: large_template.pdf

person Bruno Lowagie    schedule 17.07.2014
comment
Спасибо Бруно. Я попробовал вышеописанное, но вижу только последний фрагмент своего изображения (5000 пользовательских единиц) на первой странице моего PDF-файла, а все остальные страницы пусты. Ниже мой фрагмент кода- - person shoukatghouse; 18.07.2014
comment
Не используйте комментарии для добавления кода. Обновите свой вопрос. Также: проведите еще несколько экспериментов, прежде чем задавать вопрос. XObject формы добавляется на страницу, если вы используете addTemplate(). Теперь попробуйте разные значения для x и y. - person Bruno Lowagie; 18.07.2014
comment
Спасибо Бруно. Я пробовал разные координаты xy. Я напечатал реальный размер своего изображения, а именно 602 X 15872. Я пробовал ниже координаты x, y. Все они дают мне только последний фрагмент моего изображения на первой странице pdf, а все страницы остаются пустыми. - person shoukatghouse; 18.07.2014
comment
Извините, я пропустил добавление координат, которые я пробовал в своем предыдущем комментарии. Я пробовал (0,-15000),(0,-10000),(0,-5000),(0,0).. Я что-то упустил? - person shoukatghouse; 18.07.2014
comment
Может, тебе стоит заняться математикой. Я обновляю свой пример, исходя из вашего конкретного случая. - person Bruno Lowagie; 18.07.2014
comment
Я попросил вас заняться математикой. Вы копируете/вставляете мои значения. Люди, которые копируют/вставляют код, не понимая смысла того, что они копируют, никогда не станут настоящими разработчиками. - person Bruno Lowagie; 18.07.2014
comment
Извините, я сделал эту часть своего кода до того, как вы обновили свой фрагмент кода. С моей стороны было неудачное время для обновления моего кода здесь :). Я создаю, у меня есть только последний фрагмент изображения. Я буду обновлять дальше после того, как проделаю дополнительную работу и прочитаю. - person shoukatghouse; 18.07.2014
comment
Конечно: если в шаблоне нет данных, вы их не увидите. Вот почему я создал шаблон с тестовыми данными, которые охватывают весь шаблон. - person Bruno Lowagie; 18.07.2014
comment
Привет, Бруно. После небольшого чтения и анализа у меня это заработало. Было две проблемы: во-первых, в шаблоне не было всех данных, а во-вторых, я не использовал правильную математику, как вы уже упоминали. Я упоминаю последний решение в ответе. Еще раз большое спасибо за вашу помощь и указания .. - person shoukatghouse; 18.07.2014