层级1:在text和graphics底下,PdfWriter.getDirectContentUnder()
层级2:graphics层,Chunk, Images背景,PdfPCell的边界等
层级3:text层,Chunks, Phrases, Paragraphs 内容等
层级4:在text和graphics顶上,PdfWriter.getDirectContent()
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
public class FestivalOpening {
/** The resulting PDF. */
public static final String RESULT
= "D:/data/iText/inAction/chapter03/festival_opening.pdf";
/** The movie poster. */
public static final String RESOURCE = "E:/study/PDF/SourceCodeiText/itext-book/book/resources/img/loa.jpg";
/**
* Main method.
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
*/
public static void main(String[] args)
throws IOException, DocumentException {
// step 1
Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30);
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
// Create and add a Paragraph
Paragraph p
= new Paragraph("Foobar Film Festival", new Font(FontFamily.HELVETICA, 22));
p.setAlignment(Element.ALIGN_CENTER);
document.add(p);
// Create and add an Image
Image img = Image.getInstance(RESOURCE);
img.setAbsolutePosition(
(PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
(PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
document.add(img);
// Now we go to the next page
document.newPage();
document.add(p);
document.add(img);
// Add text on top of the image
PdfContentByte over = writer.getDirectContent();
over.saveState();
float sinus = (float)Math.sin(Math.PI / 60);
float cosinus = (float)Math.cos(Math.PI / 60);
BaseFont bf = BaseFont.createFont();
over.beginText();
over.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
over.setLineWidth(1.5f);
over.setRGBColorStroke(0xFF, 0x00, 0x00);
over.setRGBColorFill(0xFF, 0xFF, 0xFF);
over.setFontAndSize(bf, 36);
over.setTextMatrix(cosinus, sinus, -sinus, cosinus, 50, 324);
over.showText("SOLD OUT");
over.endText();
over.restoreState();
// Add a rectangle under the image
PdfContentByte under = writer.getDirectContentUnder();
under.saveState();
under.setRGBColorFill(0xFF, 0xD7, 0x00);
under.rectangle(5, 5,
PageSize.POSTCARD.getWidth() - 10, PageSize.POSTCARD.getHeight() - 10);
under.fill();
under.restoreState();
// step 5
document.close();
}
}
1、fill()填充四方形,并根据setRGBColorFill()填充,默认无边框
2、fillStroke()填充四方形,并根据setLineWidth()和默认black画边框
3、setRGBColorStroke() 设置边框颜色
4、current transformation matrix(CTM)当前转换矩阵
5、stroke() 仅画边框
6、saveState/rrestoreState 对应入栈、出栈
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
public class GraphicsStateStack {
/** The resulting PDF. */
public static final String RESULT
= "D:/data/iText/inAction/chapter03/graphics_state.pdf";
/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
*/
public static void main(String[] args)
throws IOException, DocumentException {
// step 1
Document document = new Document(new Rectangle(200, 120));
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
PdfContentByte canvas = writer.getDirectContent();
// state 1:
canvas.setRGBColorFill(0xFF, 0x45, 0x00);
// fill a rectangle in state 1
canvas.rectangle(10, 10, 60, 60);
canvas.fill();
canvas.saveState();
// state 2;
canvas.setLineWidth(3);
canvas.setRGBColorFill(0x8B, 0x00, 0x00);
// fill and stroke a rectangle in state 2
canvas.rectangle(40, 20, 60, 60);
canvas.fillStroke();
canvas.saveState();
// state 3:
canvas.concatCTM(1, 0, 0.1f, 1, 0, 0);
canvas.setRGBColorStroke(0xFF, 0x45, 0x00);
canvas.setRGBColorFill(0xFF, 0xD7, 0x00);
// fill and stroke a rectangle in state 3
canvas.rectangle(70, 30, 60, 60);
canvas.fillStroke();
canvas.restoreState();
// stroke a rectangle in state 2
canvas.rectangle(100, 40, 60, 60);
canvas.stroke();
canvas.restoreState();
// fill and stroke a rectangle in state 1
canvas.rectangle(130, 50, 60, 60);
canvas.fillStroke();
// step 5
document.close();
}
}
1、showText(),设置显示的文本
2、setTextRenderingMode()设置边框模式,setLineWidth()设置边框宽度,默认无边框
3、setFontAndSize() 设置字体和大小
4、setTextMatrix() 设置字体矩阵
5、setRGBColorStoke() 设置边框颜色
6、setRGBColorFill() 设置填充颜色
Chunk c;
String foobar = "Foobar Film Festival";
// Measuring a String in Helvetica
Font helvetica = new Font(FontFamily.HELVETICA, 12);
BaseFont bf_helv = helvetica.getCalculatedBaseFont(false);
float width_helv = bf_helv.getWidthPoint(foobar, 12);
c = new Chunk(foobar + ": " + width_helv, helvetica);
document.add(new Paragraph(c));
document.add(new Paragraph(String.format("Chunk width: %f", c.getWidthPoint())));
// Measuring a String in Times
BaseFont bf_times = BaseFont.createFont(
"c:/windows/fonts/times.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
Font times = new Font(bf_times, 12);
float width_times = bf_times.getWidthPoint(foobar, 12);
c = new Chunk(foobar + ": " + width_times, times);
document.add(new Paragraph(c));
document.add(new Paragraph(String.format("Chunk width: %f", c.getWidthPoint())));
document.add(Chunk.NEWLINE);
注意:字体大小不是某个字符的高度,而是一行的垂直空间
// Ascent and descent of the String
document.add(new Paragraph("Ascent Helvetica: "
+ bf_helv.getAscentPoint(foobar, 12)));
document.add(new Paragraph("Ascent Times: "
+ bf_times.getAscentPoint(foobar, 12)));
document.add(new Paragraph("Descent Helvetica: "
+ bf_helv.getDescentPoint(foobar, 12)));
document.add(new Paragraph("Descent Times: "
+ bf_times.getDescentPoint(foobar, 12)));
PdfContentByte canvas = writer.getDirectContent();
// Adding text with PdfContentByte.showTextAligned()
canvas.beginText();
canvas.setFontAndSize(bf_helv, 12);
canvas.showTextAligned(Element.ALIGN_LEFT, foobar, 400, 788, 0);
canvas.showTextAligned(Element.ALIGN_RIGHT, foobar, 400, 752, 0);
canvas.showTextAligned(Element.ALIGN_CENTER, foobar, 400, 716, 0);
canvas.showTextAligned(Element.ALIGN_CENTER, foobar, 400, 680, 30);
canvas.showTextAlignedKerned(Element.ALIGN_LEFT, foobar, 400, 644, 0);
canvas.endText();
// Kerned text
width_helv = bf_helv.getWidthPointKerned(foobar, 12);
c = new Chunk(foobar + ": " + width_helv, helvetica);
document.add(new Paragraph(c));
// Adding text with ColumnText.showTextAligned()
Phrase phrase = new Phrase(foobar, times);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 200, 572, 0);
ColumnText.showTextAligned(canvas, Element.ALIGN_RIGHT, phrase, 200, 536, 0);
ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 500, 0);
ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 464, 30);
ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 428, -30);
一个短句(Phrase)能够包含一系列的块(Chunk)。添加短句(Phrase)到绝对定位,可以方便地选择字体、字号和颜色,iText会自动计算短句(Phrase)内每个块(Chunk)的间距。
1、setScaling(float scale) 设置缩放比例
2、setSkew(float arg1, float arg2) 设置倾斜,arg1:基线的角度,arg2:字符对基线的角度
3、setTextRenderMode() 设置文本渲染模式
// Chunk attributes
c = new Chunk(foobar, times);
c.setHorizontalScaling(0.5f);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 572, 0);
c = new Chunk(foobar, times);
c.setSkew(15, 15);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 536, 0);
c = new Chunk(foobar, times);
c.setSkew(0, 25);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 500, 0);
c = new Chunk(foobar, times);
c.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_STROKE, 0.1f, BaseColor.RED);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 464, 0);
c = new Chunk(foobar, times);
c.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, 1, null);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 428, -0);
完整示例
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
public class FoobarFilmFestival {
public static final String RESULT
= "D:/data/iText/inAction/chapter03/foobar_film_festival.pdf";
/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
*/
public static void main(String[] args)
throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
Chunk c;
String foobar = "Foobar Film Festival";
// Measuring a String in Helvetica
Font helvetica = new Font(FontFamily.HELVETICA, 12);
BaseFont bf_helv = helvetica.getCalculatedBaseFont(false);
float width_helv = bf_helv.getWidthPoint(foobar, 12);
c = new Chunk(foobar + ": " + width_helv, helvetica);
document.add(new Paragraph(c));
document.add(new Paragraph(String.format("Chunk width: %f", c.getWidthPoint())));
// Measuring a String in Times
BaseFont bf_times = BaseFont.createFont(
"c:/windows/fonts/times.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
Font times = new Font(bf_times, 12);
float width_times = bf_times.getWidthPoint(foobar, 12);
c = new Chunk(foobar + ": " + width_times, times);
document.add(new Paragraph(c));
document.add(new Paragraph(String.format("Chunk width: %f", c.getWidthPoint())));
document.add(Chunk.NEWLINE);
// Ascent and descent of the String
document.add(new Paragraph("Ascent Helvetica: "
+ bf_helv.getAscentPoint(foobar, 12)));
document.add(new Paragraph("Ascent Times: "
+ bf_times.getAscentPoint(foobar, 12)));
document.add(new Paragraph("Descent Helvetica: "
+ bf_helv.getDescentPoint(foobar, 12)));
document.add(new Paragraph("Descent Times: "
+ bf_times.getDescentPoint(foobar, 12)));
document.add(Chunk.NEWLINE);
// Kerned text
width_helv = bf_helv.getWidthPointKerned(foobar, 12);
c = new Chunk(foobar + ": " + width_helv, helvetica);
document.add(new Paragraph(c));
// Drawing lines to see where the text is added
PdfContentByte canvas = writer.getDirectContent();
canvas.saveState();
canvas.setLineWidth(0.05f);
canvas.moveTo(400, 806);
canvas.lineTo(400, 626);
canvas.moveTo(508.7f, 806);
canvas.lineTo(508.7f, 626);
canvas.moveTo(280, 788);
canvas.lineTo(520, 788);
canvas.moveTo(280, 752);
canvas.lineTo(520, 752);
canvas.moveTo(280, 716);
canvas.lineTo(520, 716);
canvas.moveTo(280, 680);
canvas.lineTo(520, 680);
canvas.moveTo(280, 644);
canvas.lineTo(520, 644);
canvas.stroke();
canvas.restoreState();
// Adding text with PdfContentByte.showTextAligned()
canvas.beginText();
canvas.setFontAndSize(bf_helv, 12);
canvas.showTextAligned(Element.ALIGN_LEFT, foobar, 400, 788, 0);
canvas.showTextAligned(Element.ALIGN_RIGHT, foobar, 400, 752, 0);
canvas.showTextAligned(Element.ALIGN_CENTER, foobar, 400, 716, 0);
canvas.showTextAligned(Element.ALIGN_CENTER, foobar, 400, 680, 30);
canvas.showTextAlignedKerned(Element.ALIGN_LEFT, foobar, 400, 644, 0);
canvas.endText();
// More lines to see where the text is added
canvas.saveState();
canvas.setLineWidth(0.05f);
canvas.moveTo(200, 590);
canvas.lineTo(200, 410);
canvas.moveTo(400, 590);
canvas.lineTo(400, 410);
canvas.moveTo(80, 572);
canvas.lineTo(520, 572);
canvas.moveTo(80, 536);
canvas.lineTo(520, 536);
canvas.moveTo(80, 500);
canvas.lineTo(520, 500);
canvas.moveTo(80, 464);
canvas.lineTo(520, 464);
canvas.moveTo(80, 428);
canvas.lineTo(520, 428);
canvas.stroke();
canvas.restoreState();
// Adding text with ColumnText.showTextAligned()
Phrase phrase = new Phrase(foobar, times);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 200, 572, 0);
ColumnText.showTextAligned(canvas, Element.ALIGN_RIGHT, phrase, 200, 536, 0);
ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 500, 0);
ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 464, 30);
ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 428, -30);
// Chunk attributes
c = new Chunk(foobar, times);
c.setHorizontalScaling(0.5f);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 572, 0);
c = new Chunk(foobar, times);
c.setSkew(15, 15);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 536, 0);
c = new Chunk(foobar, times);
c.setSkew(0, 25);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 500, 0);
c = new Chunk(foobar, times);
c.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_STROKE, 0.1f, BaseColor.RED);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 464, 0);
c = new Chunk(foobar, times);
c.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, 1, null);
phrase = new Phrase(c);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 428, -0);
// step 5
document.close();
}
}
在文本模式下使用ColumnText
在复合模式中使用ColumnText
如何在文档重复添加image?PDF图片的字节存储在单独区域,页面包含一个图片的引用,指向external object(XObject)
顶层的图片遮盖住文本:Foobar Film Festival
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.PdfWriter;
public class ImageDirect {
/** The resulting PDF. */
public static final String RESULT
= "D:/data/iText/inAction/chapter03/image_direct.pdf";
/** The movie poster. */
public static final String RESOURCE
= "E:/study/PDF/SourceCodeiText/itext-book/book/resources/img/loa.jpg";
public static void main(String[] args)
throws IOException, DocumentException {
// step 1
Document document
= new Document(PageSize.POSTCARD, 30, 30, 30, 30);
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(RESULT));
writer.setCompressionLevel(0);
// step 3
document.open();
// step 4
Image img = Image.getInstance(RESOURCE);
img.setAbsolutePosition((PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
(PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
writer.getDirectContent().addImage(img);
Paragraph p = new Paragraph("Foobar Film Festival", new Font(FontFamily.HELVETICA, 22));
p.setAlignment(Element.ALIGN_CENTER);
document.add(p);
// step 5
document.close();
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
public class ImageSkew {
/** The resulting PDF. */
public static final String RESULT = "D:/data/iText/inAction/chapter03/image_skew.pdf";
/** The movie poster. */
public static final String RESOURCE = "E:/study/PDF/SourceCodeiText/itext-book/book/resources/img/loa.jpg";
/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
*/
public static void main(String[] args)
throws IOException, DocumentException {
// step 1
Document document = new Document(PageSize.POSTCARD.rotate());
// step 2
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(RESULT));
writer.setCompressionLevel(0);
// step 3
document.open();
// step 4
Image img = Image.getInstance(RESOURCE);
// Add the image to the upper layer
writer.getDirectContent().addImage(img,
img.getWidth(), 0, 0.35f * img.getHeight(),
0.65f * img.getHeight(), 30, 30);
// step 5
document.close();
}
}
PdfWriter.getDirectContent().addImage(img, true)
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
public class ImageInline {
/** The resulting PDF. */
public static final String RESULT
= "D:/data/iText/inAction/chapter03/image_inline.pdf";
/** The movie poster. */
public static final String RESOURCE
= "E:/study/PDF/SourceCodeiText/itext-book/book/resources/img/loa.jpg";
/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
*/
public static void main(String[] args)
throws IOException, DocumentException {
// step 1
Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30);
// step 2
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(RESULT));
writer.setCompressionLevel(0);
// step 3
document.open();
// step 4
Image img = Image.getInstance(RESOURCE);
img.setAbsolutePosition(
(PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
(PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
writer.getDirectContent().addImage(img, true);
// step 5
document.close();
}
}
PdfTemplate 对象
PdfTemplate:XObject的别称
PdfTemplate是一个PDF内容流,它是任何图形对象的序列。PdfTemplate扩展PdfContentByte并继承所有其方法。
PdfContentByte canvas = writer.getDirectContent();
// Create the XObject
PdfTemplate celluloid = canvas.createTemplate(595, 84.2f);
celluloid.rectangle(8, 8, 579, 68);
for (float f = 8.25f; f < 581; f+= 6.5f) {
celluloid.roundRectangle(f, 8.5f, 6, 3, 1.5f);
celluloid.roundRectangle(f, 72.5f, 6, 3, 1.5f);
}
celluloid.setGrayFill(0.1f);
celluloid.eoFill();
// Write the XObject to the OutputStream
writer.releaseTemplate(celluloid);
// Add the XObject 10 times
for (int i = 0; i < 10; i++) {
canvas.addTemplate(celluloid, 0, i * 84.2f);
}
// Go to the next page
document.newPage();
// Add the XObject 10 times
for (int i = 0; i < 10; i++) {
canvas.addTemplate(celluloid, 0, i * 84.2f);
}