问题描述
我正在使用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 headerHandler
和PageEndEvent 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();
...
(摘录自 InsertInSpace 助手insertIntoNithinTestFile
)
如果按原样使用原始源页面,则上面的代码将插入其中,包括所有页边距空间.如果您不希望这样做,而是减少其空间,则可以按照以下步骤确定页面内容的实际边界框,将页面缩小到该框,然后将其转发到上面的方法insertIntoNithinTestFile
并假定页面PdfDocument pdfDocument
中的1个应处理:
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");
(插入InSpace 测试testInsertSimpleTestPdf
)
MarginFinder
是iText5的端口 MarginFinder
:
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));
}
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));
}
这篇关于如何在不丢失页眉和页脚的情况下使用IText7将源PDF内容添加到目标PDF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!