• iText实战--Table、cell 和 page event


    5.1 使用表和单元格事件装饰表

    实现PdfPTableEvent 接口

    实现PdfPCellEvent 接口

    合并表格和单元格事件

    5.2 基本构建块的事件

    通用块(Chunk)功能

    段落(Paragraph)事件

    章节(Chapter)和 区域(Section)事件

    页面顺序和空白页面

    5.3 页面边界概述

    媒体盒

    作物箱

    其他页面边界

    5.4 添加页码事件到 PdfWriter

    PdfPageEvent 接口

    onOpenDocument():当文档打开后触发,初始化变量整个文档可使用

    onStartPage():当开始一个新页面触发,初始化页面级变量,不要在这个方法内添加内容

    onEndPage():开始一个新页面并在文档关闭前触发,这里添加header、footer、watermark

    onCloseDocument():文档关闭时触发,这里释放资源

    添加页头与页尾

    1. import java.io.FileOutputStream;
    2. import java.io.IOException;
    3. import java.sql.SQLException;
    4. import com.itextpdf.text.Chapter;
    5. import com.itextpdf.text.Document;
    6. import com.itextpdf.text.DocumentException;
    7. import com.itextpdf.text.Element;
    8. import com.itextpdf.text.Font;
    9. import com.itextpdf.text.PageSize;
    10. import com.itextpdf.text.Paragraph;
    11. import com.itextpdf.text.Phrase;
    12. import com.itextpdf.text.Rectangle;
    13. import com.itextpdf.text.Font.FontFamily;
    14. import com.itextpdf.text.pdf.ColumnText;
    15. import com.itextpdf.text.pdf.PdfPageEventHelper;
    16. import com.itextpdf.text.pdf.PdfWriter;
    17. public class MovieHistory2 {
    18. /** The resulting PDF file. */
    19. public static final String RESULT
    20. = "results/part1/chapter05/movie_history2.pdf";
    21. /** Inner class to add a header and a footer. */
    22. class HeaderFooter extends PdfPageEventHelper {
    23. /** Alternating phrase for the header. */
    24. Phrase[] header = new Phrase[2];
    25. /** Current page number (will be reset for every chapter). */
    26. int pagenumber;
    27. /**
    28. * Initialize one of the headers.
    29. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(
    30. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    31. */
    32. public void onOpenDocument(PdfWriter writer, Document document) {
    33. header[0] = new Phrase("Movie history");
    34. }
    35. /**
    36. * Initialize one of the headers, based on the chapter title;
    37. * reset the page number.
    38. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onChapter(
    39. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document, float,
    40. * com.itextpdf.text.Paragraph)
    41. */
    42. public void onChapter(PdfWriter writer, Document document,
    43. float paragraphPosition, Paragraph title) {
    44. header[1] = new Phrase(title.getContent());
    45. pagenumber = 1;
    46. }
    47. /**
    48. * Increase the page number.
    49. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onStartPage(
    50. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    51. */
    52. public void onStartPage(PdfWriter writer, Document document) {
    53. pagenumber++;
    54. }
    55. /**
    56. * Adds the header and the footer.
    57. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
    58. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    59. */
    60. public void onEndPage(PdfWriter writer, Document document) {
    61. Rectangle rect = writer.getBoxSize("art");
    62. switch(writer.getPageNumber() % 2) {
    63. case 0:
    64. ColumnText.showTextAligned(writer.getDirectContent(),
    65. Element.ALIGN_RIGHT, header[0],
    66. rect.getRight(), rect.getTop(), 0);
    67. break;
    68. case 1:
    69. ColumnText.showTextAligned(writer.getDirectContent(),
    70. Element.ALIGN_LEFT, header[1],
    71. rect.getLeft(), rect.getTop(), 0);
    72. break;
    73. }
    74. ColumnText.showTextAligned(writer.getDirectContent(),
    75. Element.ALIGN_CENTER, new Phrase(String.format("page %d", pagenumber)),
    76. (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0);
    77. }
    78. }
    79. /** The different epochs. */
    80. public static final String[] EPOCH =
    81. { "Forties", "Fifties", "Sixties", "Seventies", "Eighties",
    82. "Nineties", "Twenty-first Century" };
    83. /** The fonts for the title. */
    84. public static final Font[] FONT = new Font[4];
    85. static {
    86. FONT[0] = new Font(FontFamily.HELVETICA, 24);
    87. FONT[1] = new Font(FontFamily.HELVETICA, 18);
    88. FONT[2] = new Font(FontFamily.HELVETICA, 14);
    89. FONT[3] = new Font(FontFamily.HELVETICA, 12, Font.BOLD);
    90. }
    91. /**
    92. * Creates a PDF document.
    93. * @param filename the path to the new PDF document
    94. * @throws DocumentException
    95. * @throws IOException
    96. * @throws SQLException
    97. */
    98. public void createPdf(String filename)
    99. throws IOException, DocumentException, SQLException {
    100. // step 1
    101. Document document = new Document(PageSize.A4, 36, 36, 54, 54);
    102. // step 2
    103. PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
    104. HeaderFooter event = new HeaderFooter();
    105. writer.setBoxSize("art", new Rectangle(36, 54, 559, 788));
    106. writer.setPageEvent(event);
    107. // step 3
    108. document.open();
    109. // step 4
    110. Chapter chapter = null;
    111. // 初始化数据...
    112. document.add(chapter);
    113. // step 5
    114. document.close();
    115. }
    116. /**
    117. * Main method.
    118. *
    119. * @param args no arguments needed
    120. * @throws DocumentException
    121. * @throws IOException
    122. * @throws SQLException
    123. */
    124. public static void main(String[] args)
    125. throws IOException, DocumentException, SQLException {
    126. new MovieHistory2().createPdf(RESULT);
    127. }
    128. }

    解决 page X of Y 问题

    利用XObject特性,iText 真正将PdfTemplate 写入 OutputStream 是在调用releaseTemplate() 时。

    1. import java.io.FileOutputStream;
    2. import java.io.IOException;
    3. import java.sql.SQLException;
    4. import com.itextpdf.text.Document;
    5. import com.itextpdf.text.DocumentException;
    6. import com.itextpdf.text.Element;
    7. import com.itextpdf.text.ExceptionConverter;
    8. import com.itextpdf.text.Image;
    9. import com.itextpdf.text.PageSize;
    10. import com.itextpdf.text.Phrase;
    11. import com.itextpdf.text.Rectangle;
    12. import com.itextpdf.text.pdf.ColumnText;
    13. import com.itextpdf.text.pdf.PdfPCell;
    14. import com.itextpdf.text.pdf.PdfPTable;
    15. import com.itextpdf.text.pdf.PdfPageEventHelper;
    16. import com.itextpdf.text.pdf.PdfTemplate;
    17. import com.itextpdf.text.pdf.PdfWriter;
    18. public class MovieCountries1 {
    19. /** The resulting PDF file. */
    20. public static final String RESULT
    21. = "D:/data/iText/inAction/chapter05/movie_countries1.pdf";
    22. /**
    23. * Inner class to add a table as header.
    24. */
    25. class TableHeader extends PdfPageEventHelper {
    26. /** The header text. */
    27. String header;
    28. /** The template with the total number of pages. */
    29. PdfTemplate total;
    30. /**
    31. * Allows us to change the content of the header.
    32. * @param header The new header String
    33. */
    34. public void setHeader(String header) {
    35. this.header = header;
    36. }
    37. /**
    38. * Creates the PdfTemplate that will hold the total number of pages.
    39. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(
    40. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    41. */
    42. public void onOpenDocument(PdfWriter writer, Document document) {
    43. total = writer.getDirectContent().createTemplate(30, 16);
    44. }
    45. /**
    46. * Adds a header to every page
    47. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
    48. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    49. */
    50. public void onEndPage(PdfWriter writer, Document document) {
    51. PdfPTable table = new PdfPTable(3);
    52. try {
    53. table.setWidths(new int[]{24, 24, 2});
    54. table.setTotalWidth(527);
    55. table.setLockedWidth(true);
    56. table.getDefaultCell().setFixedHeight(20);
    57. table.getDefaultCell().setBorder(Rectangle.BOTTOM);
    58. table.addCell(header);
    59. table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
    60. table.addCell(String.format("Page %d of", writer.getPageNumber()));
    61. PdfPCell cell = new PdfPCell(Image.getInstance(total));
    62. cell.setBorder(Rectangle.BOTTOM);
    63. table.addCell(cell);
    64. table.writeSelectedRows(0, -1, 34, 803, writer.getDirectContent());
    65. }
    66. catch(DocumentException de) {
    67. throw new ExceptionConverter(de);
    68. }
    69. }
    70. /**
    71. * Fills out the total number of pages before the document is closed.
    72. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(
    73. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    74. */
    75. public void onCloseDocument(PdfWriter writer, Document document) {
    76. ColumnText.showTextAligned(total, Element.ALIGN_LEFT,
    77. new Phrase(String.valueOf(writer.getPageNumber() - 1)),
    78. 2, 2, 0);
    79. }
    80. }
    81. /**
    82. * Creates a PDF document.
    83. * @param filename the path to the new PDF document
    84. * @throws DocumentException
    85. * @throws IOException
    86. * @throws SQLException
    87. */
    88. public void createPdf(String filename)
    89. throws IOException, DocumentException, SQLException {
    90. // step 1
    91. Document document = new Document(PageSize.A4, 36, 36, 54, 36);
    92. // step 2
    93. PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
    94. TableHeader event = new TableHeader();
    95. writer.setPageEvent(event);
    96. // step 3
    97. document.open();
    98. // step 4
    99. // 新建页面数据...
    100. document.add(new Phrase("Hello Page 1."));
    101. document.newPage();
    102. document.add(new Phrase("Hello Page 2."));
    103. document.newPage();
    104. document.add(new Phrase("Hello Page 3."));
    105. document.newPage();
    106. document.add(new Phrase("Hello Page 4."));
    107. // step 4
    108. document.close();
    109. }
    110. /**
    111. * Main method.
    112. *
    113. * @param args no arguments needed
    114. * @throws DocumentException
    115. * @throws IOException
    116. * @throws SQLException
    117. */
    118. public static void main(String[] args)
    119. throws IOException, DocumentException, SQLException {
    120. new MovieCountries1().createPdf(RESULT);
    121. }
    122. }

    在页尾添加页码

    1. import java.io.FileOutputStream;
    2. import java.io.IOException;
    3. import java.sql.SQLException;
    4. import com.itextpdf.text.Document;
    5. import com.itextpdf.text.DocumentException;
    6. import com.itextpdf.text.ExceptionConverter;
    7. import com.itextpdf.text.PageSize;
    8. import com.itextpdf.text.Phrase;
    9. import com.itextpdf.text.pdf.BaseFont;
    10. import com.itextpdf.text.pdf.PdfContentByte;
    11. import com.itextpdf.text.pdf.PdfPageEventHelper;
    12. import com.itextpdf.text.pdf.PdfTemplate;
    13. import com.itextpdf.text.pdf.PdfWriter;
    14. /**
    15. * TODO 在此写上类的相关说明.
    16. * @author gongqiang
    17. * @version 1.0.0 2023年9月18日
    18. * @see
    19. * @since JDK 1.5.0
    20. */
    21. public class MovieCountries {
    22. /** The resulting PDF file. */
    23. public static final String RESULT
    24. = "D:/data/iText/inAction/chapter05/movie_countries.pdf";
    25. /**
    26. * Inner class to add a table as header.
    27. */
    28. class TableHeader extends PdfPageEventHelper {
    29. /** The header text. */
    30. String header;
    31. /** The template with the total number of pages. */
    32. PdfTemplate total;
    33. BaseFont baseFont;
    34. int fontSize = 14;
    35. /**
    36. * Allows us to change the content of the header.
    37. * @param header The new header String
    38. */
    39. public void setHeader(String header) {
    40. this.header = header;
    41. }
    42. /**
    43. * Creates the PdfTemplate that will hold the total number of pages.
    44. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(
    45. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    46. */
    47. public void onOpenDocument(PdfWriter writer, Document document) {
    48. total = writer.getDirectContent().createTemplate(30, 16);
    49. try {
    50. baseFont = BaseFont.createFont("D:/data/iText/fonts/simfang.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    51. } catch (Exception e) {
    52. throw new ExceptionConverter(e);
    53. }
    54. }
    55. /**
    56. * Adds a header to every page
    57. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
    58. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    59. */
    60. public void onEndPage(PdfWriter writer, Document document) {
    61. // 新建获得用户页面文本和图片内容位置的对象
    62. PdfContentByte pdfContentByte = writer.getDirectContent();
    63. // 保存图形状态
    64. pdfContentByte.saveState();
    65. String text = "页" + writer.getPageNumber() + "/";
    66. //String text = "页 99/";
    67. // 获取点字符串的宽度
    68. float textSize = baseFont.getWidthPoint(text, fontSize);
    69. pdfContentByte.beginText();
    70. // 设置随后的文本内容写作的字体和字号
    71. pdfContentByte.setFontAndSize(baseFont, fontSize);
    72. // 定位'X/'
    73. // float x = (document.right() + document.left()) / 2;
    74. float x = document.right() - 50;
    75. float y = 20f;
    76. pdfContentByte.setTextMatrix(x, y);
    77. pdfContentByte.showText(text);
    78. pdfContentByte.endText();
    79. // 将模板加入到内容(content)中- // 定位'Y'
    80. pdfContentByte.addTemplate(total, x + textSize, y);
    81. pdfContentByte.restoreState();
    82. }
    83. /**
    84. * Fills out the total number of pages before the document is closed.
    85. * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(
    86. * com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
    87. */
    88. public void onCloseDocument(PdfWriter writer, Document document) {
    89. total.beginText();
    90. total.setFontAndSize(baseFont, fontSize);
    91. total.setTextMatrix(0, 0);
    92. // 设置总页数的值到模板上,并应用到每个界面
    93. total.showText(String.valueOf(writer.getPageNumber()));
    94. //total.showText(String.valueOf("99"));
    95. total.endText();
    96. }
    97. }
    98. /**
    99. * Creates a PDF document.
    100. * @param filename the path to the new PDF document
    101. * @throws DocumentException
    102. * @throws IOException
    103. * @throws SQLException
    104. */
    105. public void createPdf(String filename)
    106. throws IOException, DocumentException, SQLException {
    107. // step 1
    108. Document document = new Document(PageSize.A4, 36, 36, 54, 36);
    109. // step 2
    110. PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
    111. TableHeader event = new TableHeader();
    112. writer.setPageEvent(event);
    113. // step 3
    114. document.open();
    115. // step 4
    116. // 新建页面数据...
    117. document.add(new Phrase("Hello Page 1."));
    118. document.newPage();
    119. document.add(new Phrase("Hello Page 2."));
    120. document.newPage();
    121. document.add(new Phrase("Hello Page 3."));
    122. document.newPage();
    123. document.add(new Phrase("Hello Page 4."));
    124. // step 4
    125. document.close();
    126. }
    127. /**
    128. * Main method.
    129. *
    130. * @param args no arguments needed
    131. * @throws DocumentException
    132. * @throws IOException
    133. * @throws SQLException
    134. */
    135. public static void main(String[] args)
    136. throws IOException, DocumentException, SQLException {
    137. new MovieCountries().createPdf(RESULT);
    138. }
    139. }

    添加水印

    如果水印是图片,可以通过PdfContentByte.addImage()、或将图片包装成ColumnText对象,或者添加到表格的cell里。

    注意:Image对象需要在onOpenDocument()方法内初始化,避免重复添加图片的字节流。

    1. import java.io.FileOutputStream;
    2. import java.io.IOException;
    3. import java.sql.SQLException;
    4. import com.itextpdf.text.Document;
    5. import com.itextpdf.text.DocumentException;
    6. import com.itextpdf.text.Element;
    7. import com.itextpdf.text.Font;
    8. import com.itextpdf.text.Font.FontFamily;
    9. import com.itextpdf.text.PageSize;
    10. import com.itextpdf.text.Phrase;
    11. import com.itextpdf.text.pdf.ColumnText;
    12. import com.itextpdf.text.pdf.GrayColor;
    13. import com.itextpdf.text.pdf.PdfPageEventHelper;
    14. import com.itextpdf.text.pdf.PdfWriter;
    15. public class MovieCountries2 extends MovieCountries1 {
    16. /** The resulting PDF file. */
    17. public static final String RESULT
    18. = "D:/data/iText/inAction/chapter05/movie_countries2.pdf";
    19. /**
    20. * Inner class to add a watermark to every page.
    21. */
    22. class Watermark extends PdfPageEventHelper {
    23. Font FONT = new Font(FontFamily.HELVETICA, 52, Font.BOLD, new GrayColor(0.75f));
    24. public void onEndPage(PdfWriter writer, Document document) {
    25. ColumnText.showTextAligned(writer.getDirectContentUnder(),
    26. Element.ALIGN_CENTER, new Phrase("FOOBAR FILM FESTIVAL", FONT),
    27. 297.5f, 421, writer.getPageNumber() % 2 == 1 ? 45 : -45);
    28. }
    29. }
    30. /**
    31. * Creates a PDF document.
    32. * @param filename the path to the new PDF document
    33. * @throws DocumentException
    34. * @throws IOException
    35. * @throws SQLException
    36. */
    37. public void createPdf(String filename)
    38. throws IOException, DocumentException, SQLException {
    39. // step 1
    40. Document document = new Document(PageSize.A4, 36, 36, 54, 36);
    41. // step 2
    42. PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
    43. TableHeader event = new TableHeader();
    44. writer.setPageEvent(event);
    45. writer.setPageEvent(new Watermark());
    46. // step 3
    47. document.open();
    48. // step 4
    49. // 新建页面数据...
    50. document.add(new Phrase("Hello Page 1."));
    51. document.newPage();
    52. document.add(new Phrase("Hello Page 2."));
    53. document.newPage();
    54. document.add(new Phrase("Hello Page 3."));
    55. document.newPage();
    56. document.add(new Phrase("Hello Page 4."));
    57. // step 5
    58. document.close();
    59. }
    60. /**
    61. * Main method.
    62. *
    63. * @param args no arguments needed
    64. * @throws DocumentException
    65. * @throws IOException
    66. * @throws SQLException
    67. */
    68. public static void main(String[] args)
    69. throws IOException, DocumentException, SQLException {
    70. new MovieCountries2().createPdf(RESULT);
    71. }
    72. }

    创建幻灯片

  • 相关阅读:
    云原生应用安全
    树莓派4B安装ffmpeg
    Consistency Models终结扩散模型
    万字C语言之分支语句和循环语句
    【开学季】如何过好大学最后一年(求赞)
    微信小程序 springboot旅游景点门票预订服务系统
    没有上司的舞会
    idea打包springboot项目成 docker 镜像方法 (详细)
    ubuntu22.04为什么鼠标会自动丢失焦点
    大数据Doris(十二):扩容缩容
  • 原文地址:https://blog.csdn.net/gqltt/article/details/132993512