• Java生成PDF笔记整理


    1. 引入依赖, groupId:com.itextpdf, version:8.0.4, artifactId如下
      kernel,io,layout,forms
      
    2. 创建pdf对象
      try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
         PdfWriter writer = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(true));
         PdfDocument pdfDoc = new PdfDocument(writer);
         Document document = new Document(pdfDoc, PageSize.LETTER);
         document.setMargins(5, 15, 36, 15);
         // 添加内容 ...
         Table table = .... ; // 创建Table对象
         document.add(table);
         //
         document.close();
         return outputStream.toByteArray() ;
      }
      
    3. 在pdf每页顶部固定位置添加页眉
       int numberOfPages = pdfDoc.getNumberOfPages();
       LocalDate now = LocalDate.now();
       String dateContent = "Date : " + now.getYear()+ "/"+ now.getMonthValue() +"/"+ now.getDayOfMonth() ;
       Paragraph dateParagraph = new Paragraph(dateContent)
               .setFontSize(7)
               .setFontColor(ColorConstants.BLACK);
       for (int i = 1; i <= numberOfPages; i++) {
           String pageContent = "Page: "+ i +" of " + numberOfPages ;
           Paragraph pageParagraph = new Paragraph( pageContent)
                   .setFontSize(7)
                   .setFontColor(ColorConstants.BLACK);
           Rectangle pageSize = pdfDoc.getPage(i).getPageSize();
           float x = pageSize.getWidth() * 0.6f -2;
           float y = pageSize.getTop() - 12;
           doc.showTextAligned(pageParagraph, x, y, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
           doc.showTextAligned(dateParagraph, x + 70, y, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
       }
      
    4. 合并pdf
      // part1Bytes、part2Bytes 为两个pdf文件的字节数组
      try(ByteArrayInputStream part1InputSteam = new ByteArrayInputStream(part1Bytes);
          ByteArrayInputStream part2InputStream = new ByteArrayInputStream(part2Bytes)){
          // Create PdfDocument object of each pdf
          PdfDocument part1Doc = new PdfDocument(new PdfReader(part1InputSteam));
          PdfDocument part2Doc = new PdfDocument(new PdfReader(part2InputStream));
          // 
          merger.merge(part1Doc, 1, part1Doc.getNumberOfPages());
          merger.merge(part2Doc, 1, part2Doc.getNumberOfPages());
          // Source documents can be closed implicitly after merging,
          // by passing true to the setCloseSourceDocuments(boolean) method
          part1Doc.close();
          part2Doc.close();
      }
      

    Table 创建及属性配置

    1. 创建Table对象
      Cell cell = ... ; 
      // columnWidth 会使得表格的列宽度按照比例分配
      float[] columnWidth = {1, 2, 1};
      Table table = new Table(UnitValue.createPercentArray(columnWidth))
      
      table.addCell(cell);
      
    2. 表格填充整个宽度
      table.useAllAvailableWidth();
      // table.setWidth(UnitValue.createPercentValue(100)); // 也可以设置宽度 
      
    3. 创建普通文本Cell
      Cell cell = new Cell() ;
      // 填充单元格内容
      Paragraph paragraph = new Paragraph(content).setFontSize(7) ;
      cell.add(paragraph);
      
    4. 设置对其方式
        Cell cell = new Cell() ;
       cell.setTextAlignment(TextAlignment.CENTER) ;
       cell.setVerticalAlignment(VerticalAlignment.MIDDLE)
       cell.setHorizontalAlignment(HorizontalAlignment.CENTER) ;
      
    5. 创建图片Cell
      ClassPathResource resource = new ClassPathResource("banner.jpg");
      byte[] bannerData = resource.getContentAsByteArray();
      ImageData imageData = ImageDataFactory.create(bannerData);
      Image banner = new Image(imageData);
      // 设置图片宽度
      banner.setWidth(80) ;
      Cell cell = new Cell().add(banner);
      
    6. 合并单元格
      table.addCell(new Cell(1, 3).add(new Paragraph("Cell with colspan 3")));
      table.addCell(new Cell(2, 1).add(new Paragraph("Cell with rowspan 2")));
      
    7. 去除表格边框
      // 这个设置不生效 table.setBorder(Border.NO_BORDER);
      Cell cell = new Cell() ;
      // ...
      cell.setBorder(Border.NO_BORDER) ;
      

    Div 使用

    1. 创建Div对象
       Paragraph divHeader = new Paragraph("Hello : 1" )
               .setFontSize(7).setMargins(0,0,0,0).setPaddings(0,0,0,0);
       Paragraph divText = new Paragraph("World : 2")
               .setFontSize(7).setMargins(0,0,0,0).setPaddings(0,0,0,0);
       Div div = new Div().add(divHeader).add(divText)
               .setWidth(160).setPaddings(8, 0, 0, 0)
               .setHorizontalAlignment(HorizontalAlignment.LEFT) ;
      

    IEventHandler 使用(符合event事件的时候在pdf中插入内容)

    1. 继承IEventHandler 接口, 实现handleEvent 方法
      public abstract class HelloHeaderEventHandler implements IEventHandler {
          private final Document doc;
          private final Table header;
          private final float tableHeight;
      
          protected HelloHeaderEventHandler(Document doc, Table header){
              this.doc = doc ;
              this.header = header ;
              this.tableHeight = this.calTableHeight(header) ;
          }
      
          @Override
          public void handleEvent(Event currentEvent) {
              PdfDocumentEvent docEvent = (PdfDocumentEvent) currentEvent;
              PdfDocument pdfDoc = docEvent.getDocument();
              PdfPage page = docEvent.getPage();
              PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);
              PageSize pageSize = pdfDoc.getDefaultPageSize();
              float coordX = pageSize.getX() + doc.getLeftMargin();
              float coordY = pageSize.getTop() - doc.getTopMargin();
              float width = pageSize.getWidth() - doc.getRightMargin() - doc.getLeftMargin();
              float height = getHeaderHeight();
              Rectangle rect = new Rectangle(coordX, coordY, width, height);
              this.doHandleEvent(canvas, rect);
          }
          
          private void doHandleEvent(PdfCanvas canvas, Rectangle rect) {
              new Canvas(canvas, rect)
                      .add(header)
                      .close();
          }
          
          private float getHeaderHeight() {
              return tableHeight;
          }
      
          private float calTableHeight(Table table){
              TableRenderer renderer = (TableRenderer) table.createRendererSubTree();
              renderer.setParent(new DocumentRenderer(doc));
              // Simulate the positioning of the renderer to find out how much space the header table will occupy.
              LayoutResult result = renderer.layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));
              return result.getOccupiedArea().getBBox().getHeight();
          }
      }
      
    2. PdfDocument 对象添加事件
      PdfWriter writer = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(true));
      PdfDocument pdfDoc = new PdfDocument(writer);
      Document document = new Document(pdfDoc, PageSize.LETTER);
      // 
      Table header = ...; // 创建Table对象
      IEventHandler eventHandler = new HelloHeaderEventHandler(document, header)
      pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, eventHandler);
      // 设置页面边距
      float topMargin = 3 + eventHandler.getHeaderHeight();
      document.setMargins(topMargin, 15, 36, 15);
      
  • 相关阅读:
    STL函数库的讲解(1)
    JS数组at函数(获取最后一个元素的方法)介绍
    Stable Diffuse 之 安装文件夹、以及操作界面 UI 、Prompt相关说明
    【无标题】
    编译原理习题两则(龙书,写出语言的正则定义)
    二叉查找树(BST)
    PADA: Example-based Prompt Learning for on-the-fly Adaptation to Unseen Domains
    git clone开启云上AI开发
    一文看懂linux 内核网络中 RPS/RFS 原理
    TinyWebServer学习笔记-threadpool
  • 原文地址:https://blog.csdn.net/yichengjie_c/article/details/139387816