如何在不丢失页眉和页脚的情况下使用IText7将源PDF内容添加到目标PDF? [英] How can i add source PDF content to destination PDF using IText7 without losing Header and Footer?

查看:581
本文介绍了如何在不丢失页眉和页脚的情况下使用IText7将源PDF内容添加到目标PDF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Itext7.我有两个PDF.源PDF包含一些内容.目标PDF具有页眉和页脚.我需要将内容从源PDF添加到页面中间的目标PDF中,而不会重叠目标PDF的页眉和页脚.有人可以帮我提供代码吗?

下面是我的代码,附件是源PDF的屏幕截图,该文件需要嵌入final.pdf

import java.io.File;
import java.io.FileOutputStream;
import java.net.MalformedURLException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.Style;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.property.VerticalAlignment;

public class TestPdf {

    public static void main(String[] args) {

        String uuid = UUID.randomUUID().toString();
          try{                           
              @SuppressWarnings("resource")
              PdfWriter writer = new PdfWriter(new FileOutputStream(new File(Paths.get("Output").toAbsolutePath()+"/final.pdf"))).setSmartMode(true);
              PdfDocument pdfDoc = new PdfDocument(writer);    
              pdfDoc.setDefaultPageSize(PageSize.A4.rotate());                                                              
              String fonts[] = {Paths.get("fonts").toAbsolutePath() + "/TREBUC.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBD.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBI.TTF",Paths.get("fonts").toAbsolutePath() + "/TREBUCIT.TTF"};
              FontProvider fontProvider = new FontProvider();
               Map<String, PdfFont> pdfFontMap = new HashMap();
              for (String font : fonts) {
                 FontProgram fontProgram = FontProgramFactory.createFont(font);
                 if(font.endsWith("TREBUC.TTF")) {
                     pdfFontMap.put("NORMAL", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 } else if(font.endsWith("TREBUCBD.TTF")) {
                     pdfFontMap.put("BOLD", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 } else if(font.endsWith("TREBUCBI.TTF")) {
                     pdfFontMap.put("BOLD_ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 } else if(font.endsWith("TREBUCIT.TTF")) {
                     pdfFontMap.put("ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 }

                 fontProvider.addFont(fontProgram);
              }
             TestPdf testPdf = new TestPdf();
              NormalPageHeader headerHandler = testPdf.new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
              pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
              PageEndEvent pageEndEvent = testPdf.new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
              pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);
              Document doc = new Document(pdfDoc);

               doc.getPageEffectiveArea(PageSize.A4.rotate());
               Table imageTable = new Table(1);
               imageTable.setBorder(Border.NO_BORDER);
               imageTable.setWidth(UnitValue.createPercentValue(100));
               Cell cell = new Cell();
               Paragraph paragraph = new Paragraph("Title");
               paragraph.setVerticalAlignment(VerticalAlignment.TOP);
               cell.add(paragraph);            
               cell.setBorder(Border.NO_BORDER);
               cell.setPaddingTop(50);
               imageTable.addCell(cell);
               doc.add(imageTable);
               doc.close();
               System.out.println("Converted to PDF Succesfully >>> convertedSvg_"+uuid+".pdf");
           }catch(Exception e){
               e.printStackTrace();
               System.out.println("Error Occured while converting to PDF = " + e.getMessage());
           }
        }   


    class NormalPageHeader implements IEventHandler {

         String header;
         Map<String, PdfFont> font;
         public NormalPageHeader(String header, Map<String, PdfFont> font) {
             this.header = header;
             this.font = font;
         }

         @Override
         public void handleEvent(Event event) {
             //Retrieve document and
                PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
                PdfDocument pdf = docEvent.getDocument();
                PdfPage page = docEvent.getPage();         
                Rectangle pageSize = page.getPageSize();
                PdfCanvas pdfCanvas = new PdfCanvas(
                page.getLastContentStream(), page.getResources(), pdf);
                Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
                  canvas.setFontSize(10f);
                  Table table = new Table(3);
                  table.setBorder(Border.NO_BORDER);
                  table.setWidth(UnitValue.createPercentValue(100));
                  Cell leftCell = new Cell();
                  leftCell.setFont(font.get("NORMAL"));
                  leftCell.setPaddingTop(15);
                  leftCell.setPaddingLeft(20);
                  leftCell.setBorder(Border.NO_BORDER);
                  leftCell.setBorderBottom(new SolidBorder(0.5f));
                  leftCell.setWidth(UnitValue.createPercentValue(33.3f));
                  Text userLabel = new Text("Username: ");
                  userLabel.setBold();
                  Paragraph paragraph = new Paragraph(userLabel);
                  Cell middleCell = new Cell();
                  middleCell.setFont(font.get("NORMAL"));
                  middleCell.setPaddingTop(15);
                  middleCell.setBorder(Border.NO_BORDER);
                  middleCell.setBorderBottom(new SolidBorder(0.5f));
                  middleCell.setWidth(UnitValue.createPercentValue(33.3f));
                  paragraph = new Paragraph("Main Header");
                  paragraph.setTextAlignment(TextAlignment.CENTER);
                  paragraph.setBold();
                  paragraph.setFontSize(12);
                  middleCell.add(paragraph);
                  String programString = "Sample header";                 
                  paragraph = new Paragraph(programString);
                  paragraph.setTextAlignment(TextAlignment.CENTER);
                  paragraph.setBold();
                  paragraph.setFontSize(10);
                  middleCell.add(paragraph);

                  table.addCell(middleCell);
                  Cell rightCell = new Cell();
                  rightCell.setFont(font.get("NORMAL"));
                  rightCell.setPaddingTop(20);
                  rightCell.setWidth(UnitValue.createPercentValue(33.3f));
                  rightCell.setHorizontalAlignment(HorizontalAlignment.RIGHT);
                  rightCell.setBorder(Border.NO_BORDER);
                  rightCell.setBorderBottom(new SolidBorder(0.5f));
                  rightCell.setPaddingRight(20);
                  //Write text at position
                  Image img;
                try {
                    img = new Image(ImageDataFactory.create(header));
                    img.setHorizontalAlignment(HorizontalAlignment.RIGHT);
                    Style style = new Style();
                    style.setWidth(91);
                    style.setHeight(25);

                     img.addStyle(style);
                     rightCell.add(img);
                     table.addCell(rightCell);
                     table.setMarginLeft(15);
                     table.setMarginRight(15);
                     canvas.add(table);
                } catch (MalformedURLException e) {

                    e.printStackTrace();
                }
         }

     }

    class PageEndEvent implements IEventHandler {

         protected PdfFormXObject placeholder;
         protected float side = 20;
         protected float x = 300;
         protected float y = 10;
         protected float space = 4.5f;
         private String bar;
         protected float descent = 3;
         Map<String, PdfFont> font;
         public PageEndEvent(String bar, Map<String, PdfFont> font) {            
             this.bar = bar;
             this.font = font;
             placeholder =new PdfFormXObject(new Rectangle(0, 0, side, side));
         }

         @Override
         public void handleEvent(Event event) {
             Table table = new Table(3);
             table.setBorder(Border.NO_BORDER);
             table.setWidth(UnitValue.createPercentValue(100));
             Cell confCell = new Cell();
             confCell.setFont(font.get("NORMAL"));
             confCell.setPaddingTop(15);
             confCell.setPaddingLeft(20);
             confCell.setBorder(Border.NO_BORDER);
             confCell.setBorderBottom(new SolidBorder(0.5f));
             confCell.setWidth(UnitValue.createPercentValue(100));
             PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
             PdfDocument pdf = docEvent.getDocument();
             PdfPage page = docEvent.getPage();
             Rectangle pageSize = page.getPageSize();
             PdfCanvas pdfCanvas = new PdfCanvas(
             page.getLastContentStream(), page.getResources(), pdf);
             Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
             Image img;
            try {
                 img = new Image(ImageDataFactory.create(bar));
                 img.setHorizontalAlignment(HorizontalAlignment.LEFT);
                 Style style = new Style();
                 style.setWidth(UnitValue.createPercentValue(100));
                 style.setHeight(50);
                 img.addStyle(style);
                 Paragraph p = new Paragraph().add("Test: Confidential");
                 p.setFont(font.get("NORMAL"));
                 p.setFontSize(8);
                 p.setFontColor(com.itextpdf.kernel.colors.ColorConstants.GRAY);
                 canvas.showTextAligned(p, x, y, TextAlignment.CENTER);
                 pdfCanvas.addXObject(placeholder, x + space, y - descent);
                 pdfCanvas.release();
            } catch (MalformedURLException e) {

                e.printStackTrace();
            }

         }

         public void writeTotal(PdfDocument pdf) {

             Canvas canvas = new Canvas(placeholder, pdf);

             canvas.showTextAligned(String.valueOf(pdf.getNumberOfPages()),

                     0, descent, TextAlignment.LEFT);

         }

     }

}

解决方案

首先,在iText体系结构中使用某些构造背后的一些字眼:

当您使用Document实例向iText应该自动布局的文档中添加内容时,假设iText可以布局内容的区域是整个页面减去页面边距.

因此,如果您通过Document以外的其他渠道添加更多页面材料,例如就像您在NormalPageHeader headerHandlerPageEndEvent pageEndEvent中所做的那样,您的责任是在上述布局区域之外(即在边距区域)这样做. (除非其他材料是背景材料,例如水印……)

为此,您应该将页边距设置得足够大,以确保其他材料在页边距中.默认情况下,页面两边的页边距设置为36pt,通常对于单行页眉或页脚而言就足够了,但对于多行页眉或页脚而言却不足.

在代码中,您将创建一个标题,该标题至少需要52pt加一点,以防止iText布局的内容触及标题行.

请记住,将给定的PdfPage sourcePage插入页面非常简单:

 ...
NormalPageHeader headerHandler = testPdf.new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
PageEndEvent pageEndEvent = testPdf.new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);

Document doc = new Document(pdfDoc);
doc.setTopMargin(55);
PdfFormXObject xobject = sourcePage.copyAsFormXObject(pdfDoc);
Rectangle xobjectBoundaryBox = xobject.getBBox().toRectangle();
xobject.getPdfObject().put(PdfName.Matrix, new PdfArray(new float[] {1, 0, 0, 1, -xobjectBoundaryBox.getLeft(), -xobjectBoundaryBox.getBottom()}));
Image image = new Image(xobject);
image.setAutoScale(true);
doc.add(image);

doc.close();
...
 

(摘录自 PdfDocumentContentParser contentParser = new PdfDocumentContentParser(pdfDocument); MarginFinder strategy = contentParser.processContent(1, new MarginFinder()); PdfPage page = pdfDocument.getPage(1); page.setCropBox(strategy.getBoundingBox()); page.setMediaBox(strategy.getBoundingBox()); insertIntoNithinTestFile(page, "test-InsertIntoNithinTestFile.pdf");

( public class MarginFinder implements IEventListener { public Rectangle getBoundingBox() { return boundingBox != null ? boundingBox.clone() : null; } @Override public void eventOccurred(IEventData data, EventType type) { if (data instanceof ImageRenderInfo) { ImageRenderInfo imageData = (ImageRenderInfo) data; Matrix ctm = imageData.getImageCtm(); for (Vector unitCorner : UNIT_SQUARE_CORNERS) { Vector corner = unitCorner.cross(ctm); addToBoundingBox(new Rectangle(corner.get(Vector.I1), corner.get(Vector.I2), 0, 0)); } } else if (data instanceof TextRenderInfo) { TextRenderInfo textRenderInfo = (TextRenderInfo) data; addToBoundingBox(textRenderInfo.getAscentLine().getBoundingRectangle()); addToBoundingBox(textRenderInfo.getDescentLine().getBoundingRectangle()); } else if (data instanceof PathRenderInfo) { PathRenderInfo renderInfo = (PathRenderInfo) data; if (renderInfo.getOperation() != PathRenderInfo.NO_OP) { Matrix ctm = renderInfo.getCtm(); Path path = renderInfo.getPath(); for (Subpath subpath : path.getSubpaths()) { for (Point point2d : subpath.getPiecewiseLinearApproximation()) { Vector vector = new Vector((float)point2d.getX(), (float)point2d.getY(), 1); vector = vector.cross(ctm); addToBoundingBox(new Rectangle(vector.get(Vector.I1), vector.get(Vector.I2), 0, 0)); } } } } else if (data != null) { logger.fine(String.format("Ignored %s event, class %s.", type, data.getClass().getSimpleName())); } else { logger.fine(String.format("Ignored %s event with null data.", type)); } } @Override public Set<EventType> getSupportedEvents() { return null; } void addToBoundingBox(Rectangle rectangle) { if (boundingBox == null) boundingBox = rectangle.clone(); else boundingBox = Rectangle.getCommonRectangle(boundingBox, rectangle); } Rectangle boundingBox = null; Logger logger = Logger.getLogger(MarginFinder.class.getName()); static List<Vector> UNIT_SQUARE_CORNERS = Arrays.asList(new Vector(0,0,1), new Vector(1,0,1), new Vector(1,1,1), new Vector(0,1,1)); }

( MarginFinder.java )

I am using Itext 7. I have two PDF's. The source PDF has some content. The destination PDF has header and footer. I have a requirement to add the content from source PDF to destination PDF in the middle of the page without overlapping header and footer of the destination PDF. Can anyone please help me with the code ?

Below is my code and attached document is the screenshot of the source PDF which needs to be embedded in the final.pdf

import java.io.File;
import java.io.FileOutputStream;
import java.net.MalformedURLException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.Style;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.property.VerticalAlignment;

public class TestPdf {

    public static void main(String[] args) {

        String uuid = UUID.randomUUID().toString();
          try{                           
              @SuppressWarnings("resource")
              PdfWriter writer = new PdfWriter(new FileOutputStream(new File(Paths.get("Output").toAbsolutePath()+"/final.pdf"))).setSmartMode(true);
              PdfDocument pdfDoc = new PdfDocument(writer);    
              pdfDoc.setDefaultPageSize(PageSize.A4.rotate());                                                              
              String fonts[] = {Paths.get("fonts").toAbsolutePath() + "/TREBUC.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBD.TTF", Paths.get("fonts").toAbsolutePath() + "/TREBUCBI.TTF",Paths.get("fonts").toAbsolutePath() + "/TREBUCIT.TTF"};
              FontProvider fontProvider = new FontProvider();
               Map<String, PdfFont> pdfFontMap = new HashMap();
              for (String font : fonts) {
                 FontProgram fontProgram = FontProgramFactory.createFont(font);
                 if(font.endsWith("TREBUC.TTF")) {
                     pdfFontMap.put("NORMAL", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 } else if(font.endsWith("TREBUCBD.TTF")) {
                     pdfFontMap.put("BOLD", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 } else if(font.endsWith("TREBUCBI.TTF")) {
                     pdfFontMap.put("BOLD_ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 } else if(font.endsWith("TREBUCIT.TTF")) {
                     pdfFontMap.put("ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
                 }

                 fontProvider.addFont(fontProgram);
              }
             TestPdf testPdf = new TestPdf();
              NormalPageHeader headerHandler = testPdf.new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
              pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
              PageEndEvent pageEndEvent = testPdf.new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
              pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);
              Document doc = new Document(pdfDoc);

               doc.getPageEffectiveArea(PageSize.A4.rotate());
               Table imageTable = new Table(1);
               imageTable.setBorder(Border.NO_BORDER);
               imageTable.setWidth(UnitValue.createPercentValue(100));
               Cell cell = new Cell();
               Paragraph paragraph = new Paragraph("Title");
               paragraph.setVerticalAlignment(VerticalAlignment.TOP);
               cell.add(paragraph);            
               cell.setBorder(Border.NO_BORDER);
               cell.setPaddingTop(50);
               imageTable.addCell(cell);
               doc.add(imageTable);
               doc.close();
               System.out.println("Converted to PDF Succesfully >>> convertedSvg_"+uuid+".pdf");
           }catch(Exception e){
               e.printStackTrace();
               System.out.println("Error Occured while converting to PDF = " + e.getMessage());
           }
        }   


    class NormalPageHeader implements IEventHandler {

         String header;
         Map<String, PdfFont> font;
         public NormalPageHeader(String header, Map<String, PdfFont> font) {
             this.header = header;
             this.font = font;
         }

         @Override
         public void handleEvent(Event event) {
             //Retrieve document and
                PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
                PdfDocument pdf = docEvent.getDocument();
                PdfPage page = docEvent.getPage();         
                Rectangle pageSize = page.getPageSize();
                PdfCanvas pdfCanvas = new PdfCanvas(
                page.getLastContentStream(), page.getResources(), pdf);
                Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
                  canvas.setFontSize(10f);
                  Table table = new Table(3);
                  table.setBorder(Border.NO_BORDER);
                  table.setWidth(UnitValue.createPercentValue(100));
                  Cell leftCell = new Cell();
                  leftCell.setFont(font.get("NORMAL"));
                  leftCell.setPaddingTop(15);
                  leftCell.setPaddingLeft(20);
                  leftCell.setBorder(Border.NO_BORDER);
                  leftCell.setBorderBottom(new SolidBorder(0.5f));
                  leftCell.setWidth(UnitValue.createPercentValue(33.3f));
                  Text userLabel = new Text("Username: ");
                  userLabel.setBold();
                  Paragraph paragraph = new Paragraph(userLabel);
                  Cell middleCell = new Cell();
                  middleCell.setFont(font.get("NORMAL"));
                  middleCell.setPaddingTop(15);
                  middleCell.setBorder(Border.NO_BORDER);
                  middleCell.setBorderBottom(new SolidBorder(0.5f));
                  middleCell.setWidth(UnitValue.createPercentValue(33.3f));
                  paragraph = new Paragraph("Main Header");
                  paragraph.setTextAlignment(TextAlignment.CENTER);
                  paragraph.setBold();
                  paragraph.setFontSize(12);
                  middleCell.add(paragraph);
                  String programString = "Sample header";                 
                  paragraph = new Paragraph(programString);
                  paragraph.setTextAlignment(TextAlignment.CENTER);
                  paragraph.setBold();
                  paragraph.setFontSize(10);
                  middleCell.add(paragraph);

                  table.addCell(middleCell);
                  Cell rightCell = new Cell();
                  rightCell.setFont(font.get("NORMAL"));
                  rightCell.setPaddingTop(20);
                  rightCell.setWidth(UnitValue.createPercentValue(33.3f));
                  rightCell.setHorizontalAlignment(HorizontalAlignment.RIGHT);
                  rightCell.setBorder(Border.NO_BORDER);
                  rightCell.setBorderBottom(new SolidBorder(0.5f));
                  rightCell.setPaddingRight(20);
                  //Write text at position
                  Image img;
                try {
                    img = new Image(ImageDataFactory.create(header));
                    img.setHorizontalAlignment(HorizontalAlignment.RIGHT);
                    Style style = new Style();
                    style.setWidth(91);
                    style.setHeight(25);

                     img.addStyle(style);
                     rightCell.add(img);
                     table.addCell(rightCell);
                     table.setMarginLeft(15);
                     table.setMarginRight(15);
                     canvas.add(table);
                } catch (MalformedURLException e) {

                    e.printStackTrace();
                }
         }

     }

    class PageEndEvent implements IEventHandler {

         protected PdfFormXObject placeholder;
         protected float side = 20;
         protected float x = 300;
         protected float y = 10;
         protected float space = 4.5f;
         private String bar;
         protected float descent = 3;
         Map<String, PdfFont> font;
         public PageEndEvent(String bar, Map<String, PdfFont> font) {            
             this.bar = bar;
             this.font = font;
             placeholder =new PdfFormXObject(new Rectangle(0, 0, side, side));
         }

         @Override
         public void handleEvent(Event event) {
             Table table = new Table(3);
             table.setBorder(Border.NO_BORDER);
             table.setWidth(UnitValue.createPercentValue(100));
             Cell confCell = new Cell();
             confCell.setFont(font.get("NORMAL"));
             confCell.setPaddingTop(15);
             confCell.setPaddingLeft(20);
             confCell.setBorder(Border.NO_BORDER);
             confCell.setBorderBottom(new SolidBorder(0.5f));
             confCell.setWidth(UnitValue.createPercentValue(100));
             PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
             PdfDocument pdf = docEvent.getDocument();
             PdfPage page = docEvent.getPage();
             Rectangle pageSize = page.getPageSize();
             PdfCanvas pdfCanvas = new PdfCanvas(
             page.getLastContentStream(), page.getResources(), pdf);
             Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
             Image img;
            try {
                 img = new Image(ImageDataFactory.create(bar));
                 img.setHorizontalAlignment(HorizontalAlignment.LEFT);
                 Style style = new Style();
                 style.setWidth(UnitValue.createPercentValue(100));
                 style.setHeight(50);
                 img.addStyle(style);
                 Paragraph p = new Paragraph().add("Test: Confidential");
                 p.setFont(font.get("NORMAL"));
                 p.setFontSize(8);
                 p.setFontColor(com.itextpdf.kernel.colors.ColorConstants.GRAY);
                 canvas.showTextAligned(p, x, y, TextAlignment.CENTER);
                 pdfCanvas.addXObject(placeholder, x + space, y - descent);
                 pdfCanvas.release();
            } catch (MalformedURLException e) {

                e.printStackTrace();
            }

         }

         public void writeTotal(PdfDocument pdf) {

             Canvas canvas = new Canvas(placeholder, pdf);

             canvas.showTextAligned(String.valueOf(pdf.getNumberOfPages()),

                     0, descent, TextAlignment.LEFT);

         }

     }

}

解决方案

First off, some words on the iText architecture behind some constructs you use:

When you use a Document instance to add content to a document that iText shall layout automatically, the assumption is that the area where iText can layout stuff is the whole page minus the page margins.

Thus, if you add further page material via other channels than the Document, e.g. like you do in your NormalPageHeader headerHandler and your PageEndEvent pageEndEvent, it is your responsibility to do so outside the layout area explained above, i.e. in the margin areas. (Unless that additional material is background stuff, like a water sign...)

For this you should set the margins large enough to guarantee that your further material is in the margins. By default the page margins are set to 36pt on each side of the page which usually is enough for a single line header or footer but not really for multi-line ones.

In your code you create a header which requires at least some 52pt plus a bit to prevent the content iText will layout from touching the header line.

Keeping that in mind it is pretty straight forward to insert a given PdfPage sourcePage into your page:

...
NormalPageHeader headerHandler = testPdf.new NormalPageHeader(Paths.get("images").toAbsolutePath() + "\\logo.png", pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
PageEndEvent pageEndEvent = testPdf.new PageEndEvent(Paths.get("images").toAbsolutePath() + "\\FooterLineExternal.png" ,pdfFontMap);
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);

Document doc = new Document(pdfDoc);
doc.setTopMargin(55);
PdfFormXObject xobject = sourcePage.copyAsFormXObject(pdfDoc);
Rectangle xobjectBoundaryBox = xobject.getBBox().toRectangle();
xobject.getPdfObject().put(PdfName.Matrix, new PdfArray(new float[] {1, 0, 0, 1, -xobjectBoundaryBox.getLeft(), -xobjectBoundaryBox.getBottom()}));
Image image = new Image(xobject);
image.setAutoScale(true);
doc.add(image);

doc.close();
...

(excerpt from InsertInSpace helper insertIntoNithinTestFile)


If you use the original source page as is, the above code will insert it including all margin space. If you don't want this but instead cut that space of, you can proceed as follows to determine the actual bounding box of the page content, reduce the page to that box, and forward it to the method insertIntoNithinTestFile above, assuming page 1 of PdfDocument pdfDocument shall be processed:

PdfDocumentContentParser contentParser = new PdfDocumentContentParser(pdfDocument);
MarginFinder strategy = contentParser.processContent(1, new MarginFinder());

PdfPage page = pdfDocument.getPage(1);
page.setCropBox(strategy.getBoundingBox());
page.setMediaBox(strategy.getBoundingBox());
insertIntoNithinTestFile(page, "test-InsertIntoNithinTestFile.pdf");

(InsertInSpace test testInsertSimpleTestPdf)

The MarginFinder is a port of the iText5 MarginFinder to iText 7:

public class MarginFinder implements IEventListener {
    public Rectangle getBoundingBox() {
        return boundingBox != null ? boundingBox.clone() : null;
    }

    @Override
    public void eventOccurred(IEventData data, EventType type) {
        if (data instanceof ImageRenderInfo) {
            ImageRenderInfo imageData = (ImageRenderInfo) data;
            Matrix ctm = imageData.getImageCtm();
            for (Vector unitCorner : UNIT_SQUARE_CORNERS) {
                Vector corner = unitCorner.cross(ctm);
                addToBoundingBox(new Rectangle(corner.get(Vector.I1), corner.get(Vector.I2), 0, 0));
            }
        } else if (data instanceof TextRenderInfo) {
            TextRenderInfo textRenderInfo = (TextRenderInfo) data;
            addToBoundingBox(textRenderInfo.getAscentLine().getBoundingRectangle());
            addToBoundingBox(textRenderInfo.getDescentLine().getBoundingRectangle());
        } else if (data instanceof PathRenderInfo) {
            PathRenderInfo renderInfo = (PathRenderInfo) data;
            if (renderInfo.getOperation() != PathRenderInfo.NO_OP)
            {
                Matrix ctm = renderInfo.getCtm();
                Path path = renderInfo.getPath();
                for (Subpath subpath : path.getSubpaths())
                {
                    for (Point point2d : subpath.getPiecewiseLinearApproximation())
                    {
                        Vector vector = new Vector((float)point2d.getX(), (float)point2d.getY(), 1);
                        vector = vector.cross(ctm);
                        addToBoundingBox(new Rectangle(vector.get(Vector.I1), vector.get(Vector.I2), 0, 0));
                    }
                }
            }
        } else if (data != null) {
            logger.fine(String.format("Ignored %s event, class %s.", type, data.getClass().getSimpleName()));
        } else {
            logger.fine(String.format("Ignored %s event with null data.", type));
        }
    }

    @Override
    public Set<EventType> getSupportedEvents() {
        return null;
    }

    void addToBoundingBox(Rectangle rectangle) {
        if (boundingBox == null)
            boundingBox = rectangle.clone();
        else
            boundingBox = Rectangle.getCommonRectangle(boundingBox, rectangle);
    }

    Rectangle boundingBox = null;
    Logger logger = Logger.getLogger(MarginFinder.class.getName());
    static List<Vector> UNIT_SQUARE_CORNERS = Arrays.asList(new Vector(0,0,1), new Vector(1,0,1), new Vector(1,1,1), new Vector(0,1,1));
}

(MarginFinder.java)

这篇关于如何在不丢失页眉和页脚的情况下使用IText7将源PDF内容添加到目标PDF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆