Используйте thing[:]
>>> a = [1,2]
>>> b = a[:]
>>> a += [3]
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>>
Возможно ли использовать pdfbox для включения других страниц PDF в качестве встроенных объектов на странице
blockquote>Это должно быть возможно. Формат PDF позволяет использовать так называемые формы xobjects для использования в качестве таких внедренных объектов. Однако я не вижу явной реализации для этого, но процедура достаточно схожа с тем, что делают
PageExtractor
илиPDFMergerUtility
.Доказательство концепции, полученное из
PageExtractor
с использованием текущего SNAPSHOT версии версии PDFBox 2.0.0:PDDocument source = PDDocument.loadNonSeq(SOURCE, null); List<PDPage> pages = source.getDocumentCatalog().getAllPages(); PDDocument target = new PDDocument(); PDPage page = new PDPage(); PDRectangle cropBox = page.findCropBox(); page.setResources(new PDResources()); target.addPage(page); PDFormXObject xobject = importAsXObject(target, pages.get(0)); page.getResources().addXObject(xobject, "X"); PDPageContentStream content = new PDPageContentStream(target, page); AffineTransform transform = new AffineTransform(0, 0.5, -0.5, 0, cropBox.getWidth(), 0); content.drawXObject(xobject, transform); transform = new AffineTransform(0.5, 0.5, -0.5, 0.5, 0.5 * cropBox.getWidth(), 0.2 * cropBox.getHeight()); content.drawXObject(xobject, transform); content.close(); target.save(TARGET); target.close(); source.close();
Этот код импортирует первую страницу исходного документа в целевой документ как объект XObject и дважды помещает его на страницу с различными преобразованиями масштабирования и вращения, например для этого источника
[/g0]
он создает это
[/g1]
Помощник метод
importAsXObject
, фактически выполняющий импорт, определяется следующим образом:PDFormXObject importAsXObject(PDDocument target, PDPage page) throws IOException { final PDStream src = page.getContents(); if (src != null) { final PDFormXObject xobject = new PDFormXObject(target); OutputStream os = xobject.getPDStream().createOutputStream(); InputStream is = src.createInputStream(); try { IOUtils.copy(is, os); } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); } xobject.setResources(page.findResources()); xobject.setBBox(page.findCropBox()); return xobject; } return null; }
Как упоминалось выше, это только доказательство концепции, угловые случаи еще не приняты во внимание.
Чтобы обновить этот вопрос:
В файле
blockquote>org.apache.pdfbox.multipdf.LayerUtility
уже есть вспомогательный класс.Пример отображения наложения PDF страница в другой PDF: SuperimposePage .
Этот класс является частью примеров Apache PDFBox и примеров преобразований, как показано в @mkl.
Так как mkl предположительно предлагается, PDFClown относится к библиотекам Java, которые обеспечивают явную поддержку для встраивания страниц (так называемые Form XObjects (см. PDF Reference 1.7, § 4.9) ).
Чтобы дать вам понять, как работает PDFClown, следующий код представляет собой эквивалент решения mbox в формате PDFBox (ПРИМЕЧАНИЕ: как было указано позже в mkl, его образец кода никоим образом не оптимизирован, поэтому это сравнение может не соответствовать фактическому статусу PDFBox - комментарии могут быть прояснены):
Document source = new File(SOURCE).getDocument();
Pages sourcePages = source.getPages();
Document target = new File().getDocument();
Page targetPage = new Page(target);
target.getPages().add(targetPage);
XObject xobject = sourcePages.get(0).toXObject(target);
PrimitiveComposer composer = new PrimitiveComposer(targetPage);
Dimension2D targetSize = targetPage.getSize();
Dimension2D sourceSize = xobject.getSize();
composer.showXObject(xobject, new Point2D.Double(targetSize.getWidth() * .5, targetSize.getHeight() * .35), new Dimension(sourceSize.getWidth() * .6, sourceSize.getHeight() * .6), XAlignmentEnum.Center, YAlignmentEnum.Middle, 45);
composer.showXObject(xobject, new Point2D.Double(targetSize.getWidth() * .35, targetSize.getHeight()), new Dimension(sourceSize.getWidth() * .4, sourceSize.getHeight() * .4), XAlignmentEnum.Left, YAlignmentEnum.Top, 90);
composer.flush();
target.getFile().save(TARGET, SerializationModeEnum.Standard);
source.getFile().close();
Сравнивая этот код с эквивалентом PDFBox, вы можете заметить некоторые существенные различия, которые показывают стиль стиля PDFClown. если какой-нибудь эксперт по PDFBox может проверить мои утверждения):
Все дело в том, что PDFClown имеет богатую архитектуру, состоящую из нескольких слоев абстракции : в соответствии с вашими требованиями вы можете выбрать наиболее подходящий стиль кодирования (либо вникать в низкоуровневые PDF- либо использовать удобную и элегантную модель высокого уровня). PDFClown позволяет вам настраивать каждый байт и решать сложные задачи с помощью смехотворно простого вызова метода по вашему желанию.
РАСКРЫТИЕ: Я являюсь ведущим разработчиком PDFClown.