2016-11-11 3 views
0

Я хочу переместить текст с помощью iText7. У меня есть ограничивающая рамка источника, которая может быть где-то на странице, и у меня есть целевая ограничивающая рамка, которая имеет фиксированную позицию (включая ширину и высоту). Я останусь на той же странице. Исходные и целевые поля могут перекрываться. Ограничивающий блок источника также может быть больше, чем целевой. В этом случае я должен уменьшить размер шрифта. Текст должен содержать шрифт, цвет и т. Д.Перемещение текста на странице с сохранением шрифта iText7, цвета, стиля, ... но изменение размера текста

На сайте iText находится cut and paste example. Но в файле pdf результата вы можете выбрать текст в новой и старой позиции (попробовал его только с обычным PDF-ридером). Я не хочу, чтобы текст можно было выбрать на старой позиции.

Я подумал, что, возможно, я мог бы выбрать текст и просто поместить его в новое положение и удалить его из старой позиции. Для последнего мне понадобится pdfSweep, но это нормально. Добавление текста в новую позицию не должно быть проблемой. Даже если текст имеет разные шрифты, размеры и т. Д. На веб-сайте iText представлено множество примеров. Единственный способ, которым я знаю, выбрать текст, как показано в этом example. Это дает мне только текст. Но чтобы разместить его в целевой позиции с тем же шрифтом, цветом и т. Д., Мне тоже нужны все эти сведения. Я знаю, что PDF не предназначен для редактирования. Это часто упоминается в ответах на StackOverflow. Есть ли способ сделать это с помощью iText7?

+0

Можете ли вы поделиться типичным примером PDF с типичными исходными и целевыми полями? – mkl

ответ

0

Там нет высокого уровня API в IText позволяет вам ход содержание страницы, в частности, не все содержимое из некоторого прямоугольника. Одна из причин может заключаться в том, что в целом это не просто перемещение. PDF-файлы часто содержат структуры, влияющие на большие площади, и такие структуры просто не нужно будет перемещать, а вместо этого копировать, и каждая копия ограничивается ее областью.

Это действительно возможно, однако, сочетать cut and paste example ОП найденную с модулем pdfSweep уже рассмотренного ОП в раствор, который предотвращает текст от того, выбирается в старой позиции, например как это:

public void moveCleanSection(PdfReader pdfReader, String targetFile, int page, Rectangle from, Rectangle to) throws IOException 
{ 
    LicenseKey.loadLicenseFile("itextkey-multiple-products.xml"); 

    ByteArrayOutputStream interimMain = new ByteArrayOutputStream(); 
    ByteArrayOutputStream interimPage = new ByteArrayOutputStream(); 
    ByteArrayOutputStream interimSection = new ByteArrayOutputStream(); 

    try ( PdfDocument pdfMainDocument = new PdfDocument(pdfReader); 
      PdfDocument pdfPageDocument = new PdfDocument(new PdfWriter(interimPage))) 
    { 
     pdfMainDocument.setCloseReader(false); 
     pdfMainDocument.copyPagesTo(page, page, pdfPageDocument); 
    } 

    try ( PdfDocument pdfMainDocument = new PdfDocument(pdfReader, new PdfWriter(interimMain)); 
      PdfDocument pdfSectionDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(interimPage.toByteArray())), 
      new PdfWriter(interimSection)) ) 
    { 

     List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>(); 
     cleanUpLocations.add(new PdfCleanUpLocation(page, from, null)); 
     cleanUpLocations.add(new PdfCleanUpLocation(page, to, null)); 

     PdfCleanUpTool cleaner = new PdfCleanUpTool(pdfMainDocument, cleanUpLocations); 
     cleaner.cleanUp(); 

     cleanUpLocations = new ArrayList<PdfCleanUpLocation>(); 
     Rectangle mediaBox = pdfSectionDocument.getPage(1).getMediaBox(); 

     if (from.getTop() < mediaBox.getTop()) 
      cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(mediaBox.getLeft(), from.getTop(), mediaBox.getWidth(), mediaBox.getTop() - from.getTop()), null)); 
     if (from.getBottom() > mediaBox.getBottom()) 
      cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(mediaBox.getLeft(), mediaBox.getBottom(), mediaBox.getWidth(), from.getBottom() - mediaBox.getBottom()), null)); 
     if (from.getLeft() > mediaBox.getLeft()) 
      cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(mediaBox.getLeft(), mediaBox.getBottom(), from.getLeft() - mediaBox.getLeft(), mediaBox.getHeight()), null)); 
     if (from.getRight() < mediaBox.getRight()) 
      cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(from.getRight(), mediaBox.getBottom(), mediaBox.getRight() - from.getRight(), mediaBox.getHeight()), null)); 

     cleaner = new PdfCleanUpTool(pdfSectionDocument, cleanUpLocations); 
     cleaner.cleanUp(); 
    } 

    try ( PdfDocument pdfSectionDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(interimSection.toByteArray()))); 
      PdfDocument pdfMainDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(interimMain.toByteArray())), new PdfWriter(targetFile))) 
    { 
     float scale = Math.min(to.getHeight()/from.getHeight(), to.getWidth()/from.getWidth()); 
     pdfSectionDocument.getPage(1).setMediaBox(from); 
     PdfFormXObject pageXObject = pdfSectionDocument.getFirstPage().copyAsFormXObject(pdfMainDocument); 
     PdfPage pdfPage = pdfMainDocument.getPage(page); 
     PdfCanvas pdfCanvas = new PdfCanvas(pdfPage); 
     pdfCanvas.addXObject(pageXObject, scale, 0, 0, scale, (to.getLeft() - from.getLeft() * scale), (to.getBottom() - from.getBottom() * scale)); 
    } 
} 

(От MoveSectionCleanly.java)

Осторожно: Из-за природы pdfSweep, текст находящийся на границе исходной области удаляется как из источника и его копии.

+1

Извините за мой (очень) поздний ответ. Большое спасибо. Создание копии раздела, масштабирование и размещение на странице не пришло мне в голову. – Nick

 Смежные вопросы

  • Нет связанных вопросов^_^