Любой API, который позволяет вам импортировать страницы и записывать непосредственно в поток содержимого PDF, позволит вам сделать это.
В iText (Java) это будет выглядеть примерно так:
PdfReader reader = new PdfReader(pdfPath);
Document doc = new Document();
PdfWriter writer = PdfWriter.getInstance( doc, new FileOutputStream(outPath) );
for (int pageNum = 1; pageNum <= reader.getNumberOfPages(); ++pageNum) {
PdfImportedPage page = writer.getImportedPage(reader, pageNum);
PdfContentByte pageContent = writer.getDirectContent();
// flip around vertical axis
pageContent.addTemplate(page, 1f, 0f, 0f, -1f, page.getWidth(), 0f);
doc.newPage();
}
Приведенный выше код выполняет следующие задницы:
- Размер страницы по умолчанию
Document()
соответствует размеру текущего PdfImportedPage
.
- Исходные страницы не поворачиваются.
- Нет аннотаций, необязательных групп содержимого (слоев) и различных других битов, которые не просто представлены в содержимом страницы.
Некоторые обходные пути:
// keep the page size consistent
PdfImportedPage page = writer.getImportedPage(reader, pageNum);
doc.newPage(page.getBoundingBox());
PdfContentByte pageContent = writer.getDirectContent();
pageContent.addTemplate(...);
// to compensate for a page's rotation, you need to either rotate the target page
// Easy in PdfStamper, virtually impossible with `Document` / `PdfWriter`.
AffineTransform unRotate = AffineTranform.getRotateInstance(degToRad(360 - pageRotation), pageCenterX, pageCenterY)
AffineTransform flip = new AffineTransform(1f, 0f, 0f, -1f, page.getWidth(), 0f);
AffineTransform finalTrans = flip;
finalTrans.concatenate(unRotate);
pageContent.addTemplate(page, finalTrans);
ЯРМАРКА ПРЕДУПРЕЖДЕНИЯ: мой 2-й матричный фу не такой сильный Я почти наверняка делаю что-то не так. Отладка такого рода вещей - настоящая PITA. Материал либо «выглядит правильно», либо так сильно испортил его полностью со страницы (эргономически невидим, так что вы не знаете, в какую сторону это пошло). Я часто меняю прямоугольники страницы на [-1000 -1000 1000 1000], чтобы видеть, куда все это делось. Прикольные вещи.
Что касается копирования аннотаций и тому подобного ... ой. PdfCopy делает все это за вас, используя метод addPage()
, но это не позволяет вам сначала преобразовывать содержимое страницы. Любые изменения, которые вы делаете в PdfImportedPage, игнорируются. Вы действительно застряли с The Hard Way ... вручную скопировав все ненужные биты и изменив их, чтобы компенсировать перевернутую страницу ... или возиться с источником на addPage()
, чтобы получить желаемые результаты. И то, и другое требует глубоких знаний PDF.
Учитывая специфику, вам, вероятно, не нужно беспокоиться об этом, но стоит упомянуть, если кто-то с другой ситуацией достигнет той же цели.