2016-11-11 422 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結合與已經由OP認爲這防止文本從舊的位置,例如是可選擇的溶液pdfSweep模塊中發現的OP像這樣:

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