Itextpdf添加页眉页脚页码

Love The Way You Lie 2023-02-17 02:51 138阅读 0赞

项目需要样式比较复杂,刚开始因为时间比较紧所以采用了Itextpdf插件代码生成pdf ,实话说过程十分繁琐,因为pdf文件样式比较多,表格也比较多,各种的表格,还有就是页眉页脚页码都要自己找页面位置坐标但是又不能像html那样方便更改查看样式,只能改一点导出来看看合适不,然后再改再导出来看。
私下调研了很多,现在罗列一下我所用到的一些样式处理,希望可以帮助需要做这个功能的朋友少踩坑,少尝试,直接出完美pdf报告。

  1. 封面
    在这里插入图片描述
  2. 首页在这里插入图片描述
    封面右上角那个图片可以换成logo,我做的大概是这样的一个样子,上代码

    //定义 页面大小,以及页边距左右上下
    package com.example.demo.controller;

    import com.example.demo.config.PDFConfig;
    import com.example.demo.utils.PDFBuilder;
    import com.itextpdf.text.*;
    import com.itextpdf.text.pdf.BaseFont;
    import com.itextpdf.text.pdf.PdfPCell;
    import com.itextpdf.text.pdf.PdfPTable;
    import com.itextpdf.text.pdf.PdfWriter;
    import com.itextpdf.text.pdf.draw.LineSeparator;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.FileOutputStream;
    import java.io.IOException;

    /**

    • @author hongli.zhang
    • @create 2020/5/26 13:02
      **/

    @RestController
    @RequestMapping(“/businessApplication/“)
    public class PdfContrller {

    1. @Autowired
    2. PDFConfig config;//这个是配置类,里面设置了需要用到的字体和logo图片的绝对路径
    3. public static void setImg(PdfWriter writer, String path, float fitWidth, float fitHeight, float absoluteX, float absoluteY) {
    4. try {
    5. Image image = Image.getInstance(path);
    6. image.setAlignment(Image.MIDDLE);
    7. image.scaleToFit(fitWidth, fitHeight);
    8. image.setAbsolutePosition(absoluteX, absoluteY);
    9. writer.getDirectContent().addImage(image);
    10. }catch(Exception e){
    11. }
    12. }
    13. @GetMapping("/test")
    14. public void test(HttpServletRequest requ, HttpServletResponse resp) throws DocumentException {

    //设置页面大小为A4纸大小,以及页边距左右上下

    1. Document document = new Document(PageSize.A4, 100F, 100F, 80F, 120F);
    2. PdfWriter writer = null;
    3. try {
    4. FileOutputStream out = new FileOutputStream("E:\\new.pdf");
    5. writer = PdfWriter.getInstance(document, out);
    6. } catch ( IOException | DocumentException e) {
    7. e.printStackTrace();
    8. }
    9. // 定义页眉和页脚页码事件,PDFBuilder代码在后面
    10. PDFBuilder builder = new PDFBuilder();
    11. //设置页面监听事件
    12. writer.setPageEvent(builder);
    13. document.open();
    14. //换行
    15. Paragraph newLine = new Paragraph("\n");
    16. float tableWidthPercentage = 100f; //表格的整体宽度
    17. //表格背景色
    18. BaseColor green = new BaseColor(175, 215, 136);
    19. BaseColor blue = new BaseColor(148, 170, 214);
    20. //图标
    21. setImg(writer, config.getLogo(), 130, 100, document.getPageSize().getRight(230), 700);
    22. //所需字体
    23. String fontPath = config.getCalibri();
    24. String fontBlodPath = config.getCalibrib();
    25. BaseFont bf = null;
    26. BaseFont blodbf = null;

    // BaseFont chineseFont = null;
    // BaseFont chineseBlodFont = null;

    1. try {
    2. bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    3. blodbf = BaseFont.createFont(fontBlodPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

    // chineseFont = BaseFont.createFont(“STSongStd-Light”, “UniGB-UCS2-H”, BaseFont.NOT_EMBEDDED);

    1. } catch (IOException | DocumentException e) {
    2. e.printStackTrace();
    3. }
    4. Font coverFont = new Font(blodbf, 30, Font.NORMAL);
    5. Font titleFont = new Font(blodbf, 16, Font.NORMAL);
    6. Font coverTiletFontMarked = new Font(blodbf, 16f, Font.NORMAL, new BaseColor(148, 170, 214));
    7. Font textFontBold = new Font(blodbf, 10.5f, Font.NORMAL);
    8. Font textFont = new Font(bf, 10.5f, Font.NORMAL);
    9. Font textFontGray = new Font(blodbf, 10.5f, Font.NORMAL, new BaseColor(215, 215, 215));
    10. Font chapterFont = new Font(blodbf, 14f, Font.NORMAL);

    // Font coverFont = new Font(chineseFont, 30, Font.NORMAL);
    // Font titleFont = new Font(chineseFont, 16, Font.NORMAL);
    // Font coverTiletFontMarked = new Font(chineseFont, 16f, Font.NORMAL, new BaseColor(148, 170, 214));
    // Font textFontBold = new Font(chineseFont, 10.5f, Font.NORMAL);
    // Font textFont = new Font(chineseFont, 10.5f, Font.NORMAL);
    // Font textFontGray = new Font(chineseFont, 10.5f, Font.NORMAL, new BaseColor(215, 215, 215));
    // Font chapterFont = new Font(chineseFont, 14f, Font.NORMAL);

  1. //封面
  2. Paragraph cover = new Paragraph("\n\n\n"+"CompanyName In Here HAHAHAHAH"+"\nMy Company REPORT",coverFont);
  3. cover.setAlignment(Element.ALIGN_CENTER);
  4. Paragraph paragraph1 = new Paragraph("\n\n\nREPORT DATE: " +"2020/05/03 12:02:15", titleFont);
  5. paragraph1.setAlignment(Element.ALIGN_RIGHT);
  6. cover.add(paragraph1);
  7. cover.add(new LineSeparator(5f, 100, new BaseColor(148, 170, 214), Element.ALIGN_CENTER, 30f));
  8. cover.add(newLine);
  9. Paragraph paragraph2 = new Paragraph("REPORT ID: " + "B124568744", coverTiletFontMarked);
  10. paragraph2.setAlignment(Element.ALIGN_RIGHT);
  11. cover.add(paragraph2);
  12. document.add(cover);
  13. document.newPage();
  14. //添加首页
  15. Paragraph home = new Paragraph(new Chunk("MY Report\n", chapterFont));
  16. home.add(new Chunk("Report Type: Entity\n\n", textFontGray));
  17. home.add(new Chunk("Company Name:\n", textFontBold));
  18. home.add(new Chunk("JKLJI HJKHK NJNJ UHIU", titleFont));
  19. document.add(home);
  20. // document.add(line);
  21. document.add(newLine);
  22. document.add(newLine);
  23. PdfPTable riskDashTb = new PdfPTable(2);
  24. riskDashTb.setWidths(new float[]{0.4f, 0.6f});// 每个单元格占多宽
  25. riskDashTb.setWidthPercentage(tableWidthPercentage);
  26. riskDashTb.addCell(getCell(new Phrase("level", textFontBold), blue, 1, 1));
  27. riskDashTb.addCell(getCell(new Phrase("countryCode", textFont), blue, 1, 1));
  28. riskDashTb.addCell(getCell(new Phrase("Amount", textFontBold), null, 1, 1));
  29. riskDashTb.addCell(getCell(new Phrase("nationality", textFont), null, 1, 1));
  30. riskDashTb.addCell(getCell(new Phrase("Converted Credit Amount", textFontBold), blue, 1, 1));
  31. riskDashTb.addCell(getCell(new Phrase("addr", textFont), blue, 1, 1));
  32. riskDashTb.addCell(getCell(new Phrase("currency", textFontBold), null, 1, 1));
  33. riskDashTb.addCell(getCell(new Phrase("busiZip", textFont), null, 1, 1));
  34. riskDashTb.addCell(getCell(new Phrase("level", textFontBold), blue, 1, 1));
  35. riskDashTb.addCell(getCell(new Phrase("countryCode", textFont), blue, 1, 1));
  36. riskDashTb.addCell(getCell(new Phrase("Amount", textFontBold), null, 1, 1));
  37. riskDashTb.addCell(getCell(new Phrase("nationality", textFont), null, 1, 1));
  38. riskDashTb.addCell(getCell(new Phrase("Converted Credit Amount", textFontBold), blue, 1, 1));
  39. riskDashTb.addCell(getCell(new Phrase("addr", textFont), blue, 1, 1));
  40. riskDashTb.addCell(getCell(new Phrase("currency", textFontBold), null, 1, 1));
  41. riskDashTb.addCell(getCell(new Phrase("busiZip", textFont), null, 1, 1));
  42. riskDashTb.addCell(getCell(new Phrase("level", textFontBold), blue, 1, 1));
  43. riskDashTb.addCell(getCell(new Phrase("countryCode", textFont), blue, 1, 1));
  44. riskDashTb.addCell(getCell(new Phrase("Amount", textFontBold), null, 1, 1));
  45. riskDashTb.addCell(getCell(new Phrase("nationality", textFont), null, 1, 1));
  46. riskDashTb.addCell(getCell(new Phrase("Converted Credit Amount", textFontBold), blue, 1, 1));
  47. riskDashTb.addCell(getCell(new Phrase("addr", textFont), blue, 1, 1));
  48. riskDashTb.addCell(getCell(new Phrase("currency", textFontBold), null, 1, 1));
  49. riskDashTb.addCell(getCell(new Phrase("busiZip", textFont), null, 1, 1));
  50. document.add(riskDashTb);
  51. document.add(newLine);
  52. document.add(new Paragraph("Note: The sdsd sdsd dsds is sd through a sdsds model that sdsd the sdsd of dsd of the sdsdsd company. aaa Amount is asas asa on sds saa dsdand other sdsd information.", textFont));
  53. document.add(newLine);
  54. Paragraph end = new Paragraph("End of the My Report", titleFont);
  55. end.setAlignment(Element.ALIGN_CENTER);
  56. document.add(end);
  57. document.close();
  58. // resp.getWriter().print("success");
  59. }
  60. private PdfPCell getCell(Phrase phrase, BaseColor color, int colSpan, int rowSpan) {
  61. PdfPCell cells = new PdfPCell(phrase);
  62. cells.setUseAscender(true);
  63. cells.setMinimumHeight(20f);
  64. cells.setHorizontalAlignment(Element.ALIGN_LEFT);
  65. cells.setVerticalAlignment(5);
  66. cells.setColspan(colSpan);
  67. cells.setRowspan(rowSpan);
  68. cells.setNoWrap(false);
  69. if (color != null) {
  70. cells.setBackgroundColor(color);
  71. }
  72. return cells;
  73. }
  74. }

接下来是页眉页脚事件的代码PDFBUilder
因为页眉页脚都是带格式的,所以需要一点一点拼接起来,页眉中需要添加logo图片,位置是通过代码中的x,y坐标指定的

  1. package com.example.demo.utils;
  2. import com.example.demo.config.PDFConfig;
  3. import com.itextpdf.text.*;
  4. import com.itextpdf.text.pdf.*;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.stereotype.Component;
  8. import java.io.IOException;
  9. /**
  10. * 设置页面附加属性
  11. *
  12. * @author hongli.zhang
  13. * @create 2020/5/18 21:00
  14. **/
  15. @Component
  16. public class PDFBuilder extends PdfPageEventHelper {
  17. private static final Logger LOGGER = LoggerFactory.getLogger(PDFBuilder.class);
  18. public Phrase header;
  19. public Phrase footer;
  20. // 模板
  21. public PdfTemplate total;
  22. // 基础字体对象
  23. public BaseFont bf = null;
  24. // 利用基础字体生成的字体对象,一般用于生成中文文字
  25. public Font fontDetail = null;
  26. public PDFBuilder() {
  27. }
  28. public PDFBuilder(Phrase header, Phrase footer) {
  29. this.header = header;
  30. this.footer = footer;
  31. }
  32. public void setHeader(Phrase header) {
  33. this.header = header;
  34. }
  35. public void setFooter(Phrase footer) {
  36. this.footer = footer;
  37. }
  38. /**
  39. * 文档打开时创建模板
  40. *
  41. * @param writer
  42. * @param document
  43. */
  44. public void onOpenDocument(PdfWriter writer, Document document) {
  45. total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高
  46. }
  47. /**
  48. * 关闭每页的时候,写入页眉,页脚。
  49. *
  50. * @param writer
  51. * @param document
  52. */
  53. public void onEndPage(PdfWriter writer, Document document) {
  54. this.addPage(writer, document);
  55. //this.addWatermark(writer);
  56. }
  57. public static void setImg(PdfWriter writer, String path, float fitWidth, float fitHeight, float absoluteX, float absoluteY) {
  58. try {
  59. Image image = Image.getInstance(path);
  60. image.setAlignment(Image.MIDDLE);
  61. image.scaleToFit(fitWidth, fitHeight);
  62. image.setAbsolutePosition(absoluteX, absoluteY);
  63. writer.getDirectContent().addImage(image);
  64. } catch (Exception e) {
  65. LOGGER.error("[ERROR] Set Img : img file does not exist.");
  66. }
  67. }
  68. //加分页
  69. public void addPage(PdfWriter writer, Document document) {
  70. PDFConfig config = InjectUtil.getInstance().getConfig();
  71. if (document.getPageNumber() > 1) {
  72. try {
  73. bf = BaseFont.createFont(config.getCalibri(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
  74. } catch (DocumentException e) {
  75. e.printStackTrace();
  76. } catch (IOException e) {
  77. e.printStackTrace();
  78. }
  79. BaseFont blodf = null;
  80. try {
  81. blodf = BaseFont.createFont(config.getCalibrib(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
  82. } catch (DocumentException e) {
  83. e.printStackTrace();
  84. } catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. fontDetail = new Font(bf, 9, Font.NORMAL);// 数据体字体
  88. Font titleFnot = new Font(blodf, 10.5f, Font.NORMAL);
  89. Font blodFnot = new Font(blodf, 9f, Font.NORMAL);
  90. Font font = new Font(bf, 10.5f, Font.NORMAL);
  91. setImg(writer, "D:\\ceshi.jpg", 85, 45, 65, 785);
  92. Phrase pageNumberPh = new Phrase(String.valueOf(document.getPageNumber() - 1), fontDetail);
  93. float center = document.getPageSize().getRight() / 2;//页面的水平中点
  94. float left = document.getPageSize().getLeft(90);//页面的z左边距
  95. float headerleft = document.getPageSize().getLeft(180);//页面的z左边距
  96. float right = document.getPageSize().getRight(90);//页面的z左边距
  97. float top = document.getPageSize().getTop() - 36;
  98. float bottom = document.getPageSize().getBottom() + 36;
  99. header = new Paragraph("Beijing XXXX Information Technology Hn.,JKI.", titleFnot);
  100. Paragraph header1 = new Paragraph("5f, building C2, hkhkjhd Industrial Park,", font);
  101. Paragraph header2 = new Paragraph("No. 44, Changhu Road, Jiangxi Industrial Park", font);
  102. Paragraph header3 = new Paragraph("www.xxx.com", font);
  103. Paragraph header4 = new Paragraph("China (sss) xxxxxxxxxxxx Dgyhi Code Zone", font);
  104. Paragraph header5 = new Paragraph("400-1234-567", font);
  105. Paragraph footer1 = new Paragraph("Acnnecfds Kdjklsnf", blodFnot);
  106. Paragraph footer2 = new Paragraph("The dfdfdf fddffdfdf by fdfdf in thfdfiscxcx fdfd is based on fdfd fdfd has been fdf fdfdf fdfdfdfd erwerwerwerwrww",
  107. new Font(bf, 9, Font.NORMAL));
  108. Paragraph footer3 = new Paragraph("ffdfdf and fdfdf fffdfd. fdsf fdfd fdfdf xcxcfdfd fdf fdf fdfd to fdfd that the dfdfdssxx is fdfdfdf and werwerwe",
  109. new Font(bf, 9, Font.NORMAL));
  110. Paragraph footer4 = new Paragraph("seewwdrr, we fdf fdfdf fdfd any fdfdfdxcx for fddfdfdfd, fdfdf, fdferere rererer or rer-rere rer and a werwerwer",
  111. new Font(bf, 9, Font.NORMAL));
  112. Paragraph footer5 = new Paragraph("rerer or rer of the rererer in rere rerer cxcxcxcxrer rere the retg of tfhe fffgvfgddsss on its sdfsd. The dddddw ",
  113. new Font(bf, 9, Font.NORMAL));
  114. Paragraph footer6 = new Paragraph("information dsfsdf is DSFSDS DFFDDD and Sdcxvxcvdfdfsd not be dfsdfsdf to any sdfsdf sdfsdfsd the dsfsdfsfdsdfee ",
  115. new Font(bf, 9, Font.NORMAL));
  116. Paragraph footer7 = new Paragraph("erdsfsdfsd. sdfsdf dsfsdf & dsfsdf dsfsdf sdfsdf of any sfddsfsdf dfdfdfdf the dfdf of the inforfmationssdeeetyy ",
  117. new Font(bf, 9, Font.NORMAL));
  118. // Paragraph footer8 = new Paragraph("dfdfddff in this report.", new Font(bf, 9, Font.NORMAL));
  119. Paragraph footer9 = new Paragraph("[fdddfdfdfdf]", blodFnot);
  120. // ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, headerImg, center, top, 0); //页眉图标
  121. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, header, headerleft, top + 13, 0); //页眉标题
  122. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, header1, headerleft, top - 3, 0); //页眉内容
  123. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, header2, headerleft, top - 15, 0); //页眉
  124. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_RIGHT, header3, right, top - 15, 0); //页眉
  125. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, header4, headerleft, top - 30, 0); //页眉
  126. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_RIGHT, header5, right, top - 30, 0); //页眉
  127. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_RIGHT, pageNumberPh, right, bottom + 65, 0); //页码
  128. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, footer1, center, bottom + 60, 0); //页脚标题
  129. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer2, left, bottom + 50, 0); //页脚
  130. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer3, left, bottom + 40, 0); //页脚
  131. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer4, left, bottom + 30, 0); //页脚
  132. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer5, left, bottom + 20, 0); //页脚
  133. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer6, left, bottom + 10, 0); //页脚
  134. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer7, left, bottom, 0); //页脚
  135. // ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, footer8, left, bottom - 10, 0); //页脚
  136. ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, footer9, center, bottom - 20, 0); //页脚
  137. }
  138. }
  139. //加水印
  140. public void addWatermark(PdfWriter writer) {
  141. // 水印图片
  142. Image image;
  143. try {
  144. image = Image.getInstance("");
  145. PdfContentByte content = writer.getDirectContentUnder();
  146. content.beginText();
  147. // 开始写入水印
  148. for (int k = 0; k < 5; k++) {
  149. for (int j = 0; j < 4; j++) {
  150. image.setAbsolutePosition(150 * j, 170 * k);
  151. content.addImage(image);
  152. }
  153. }
  154. content.endText();
  155. } catch (IOException | DocumentException e) {
  156. // TODO Auto-generated catch block
  157. e.printStackTrace();
  158. }
  159. }
  160. /*
  161. *
  162. *
  163. * TODO 关闭文档时,替换模板,完成整个页眉页脚组件
  164. * @see PdfPageEventHelper#onCloseDocument(PdfWriter,
  165. * Document)
  166. */
  167. public void onCloseDocument(PdfWriter writer, Document document) {
  168. // 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。
  169. total.beginText();
  170. total.setFontAndSize(bf, 9);// 生成的模版的字体、颜色
  171. String foot2 = " " + (writer.getPageNumber()) + " 页"; //页脚内容拼接 如 第1页/共2页
  172. total.showText(foot2);// 模版显示的内容
  173. total.endText();
  174. total.closePath();
  175. }
  176. }

大概覆盖了大部分的功能,当然还有给字体加背景色,字体加颜色,和比较复杂的表格制作
比如需要将list中的数据按年份横排
在这里插入图片描述
我罗列出来可能需要用到的网站地址,

发表评论

表情:
评论列表 (有 0 条评论,138人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java 添加Word页眉

    本篇文章将介绍通过java程序来添加Word页眉页脚的方法。鉴于在不同文档中,对页眉页脚的操作要求不同,文章将分别从以下几种情况来阐述: 1.添加页眉页脚 添加图片到

    相关 PDF页眉怎么设置

      页眉和页脚:通常显示文档的附加信息,常用来插入时间、日期、页码、单位名称、微标等。其中,页眉在页面的顶部,页脚在页面的底部。相信在Word里面添加页眉页脚大家都知道该怎么做

    相关 Java 插入Excel页眉

    在Excel文档中,我们常用页眉页脚来显示文档的附加信息,例如日期、公司名称、Logo或作者信息等。本文将通过Java程序来介绍如何给Excel文档添加页眉页脚。代码示例...