pdfBox在pdf指定位置添加表格和内容

功能描述:在右上角指定位置添加表格和文本。

实现思路:读取pdf,在指定位置画线,线段组成表格;指定位置也就是表格内写入文字。所有pdf坐标原点(0,0)都为左下角。

遇到问题:坐标原点大部分在左下角,有时会在其他地方。后来发现在创建PDPageContentStream对象时,引用参数为AppendMode.APPEND(所有内容流之后插入内容)改为AppendMode.PREPEND(在所有内容流之前插入内容),此时坐标原点为左下角。

实现效果:
在这里插入图片描述

代码如下:

package com.gtzn.common.utils;

import org.apache.log4j.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import java.awt.*;
import java.io.File;
import java.io.IOException;

/**
 * @author 
 * @title PdfAddSealUtil
 * @Description:
 * @date 2020/8/5
 */
public class PdfAddSealUtil {
    private static Logger logger = Logger.getLogger(PdfAddSealUtil.class);

    public static void main(String args[]) {

        new PdfAddSealUtil().addSeal("F:/Administrator/Desktop/处理.pdf", "F:/Administrator/Desktop/1232.pdf", "中国", "文书", "2020", "办公室", "30年", "numb");

    }

    public boolean addSeal(String inPath, String outPath, String qz, String lb, String year, String dep, String deadline, String numb) {
        try {
            File file = new File(inPath);
            if(!file.exists()){
                logger.debug("找不到文件:"+inPath);
            }
            // 文件夹不存在新建文件夹
            String outDir = outPath.substring(0,outPath.lastIndexOf("/"));
            File outDirFile = new File(outDir);
            if(!outDirFile.exists()){
                outDirFile.mkdirs();
                logger.debug("归档章,新建文件夹成功:"+outDir);
            }

            PDDocument doc = PDDocument.load(file);
            // 导入楷体
            PDFont font = PDType0Font.load(doc, this.getClass().getResourceAsStream(
                    "/simkai.ttf"));

            PDPage page = doc.getPage(0);
            PDPageContentStream contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.PREPEND,false, false);
            float width = page.getMediaBox().getWidth();
            float height = page.getMediaBox().getLowerLeftY()+page.getMediaBox().getHeight();

            // 表格起始x,y坐标;印章距离右上角各5mm
            float x= width-countMM(95);
            float y= height-countMM(12);
            // 所有表格高度mm转point
            float allTableheight1 = countMM(8);
            float allTableheight2 = countMM(8);
            // 上层左起第一个表格
            float topOneTableWidth = countMM(75);// 宽度

            // 上层左起第二个表格
            float topTwoTableWidth = countMM(15);
            float topTwoTableX = x+topOneTableWidth;

            float bottomTableY = y-allTableheight2;
            // 下层左起第一个表格
            float bottomOneTableWidth = countMM(11);

            // 下层左起第二个表格
            float bottomTwoTableWidth = countMM(53);
            float bottomTwoTableX = x+bottomOneTableWidth;

            float bottomThreeTableWidth = countMM(11);
            float bottomThreeTableX = bottomTwoTableX+bottomTwoTableWidth;

            float bottomFourTableWidth = countMM(15);
            float bottomFourTableX = bottomThreeTableX+bottomThreeTableWidth;

            // 画表格
            drawTable(contentStream, x,y,topOneTableWidth,allTableheight1);
            drawTable(contentStream, topTwoTableX,y,topTwoTableWidth,allTableheight1);
            drawTable(contentStream, x,bottomTableY,bottomOneTableWidth,allTableheight2);
            drawTable(contentStream, bottomTwoTableX,bottomTableY,bottomTwoTableWidth,allTableheight2);
            drawTable(contentStream, bottomThreeTableX,bottomTableY,bottomThreeTableWidth,allTableheight2);
            drawTable(contentStream, bottomFourTableX,bottomTableY,bottomFourTableWidth,allTableheight2);

            // 文字上移2毫米,居中
            float move2mm = countMM(3);
            int fontSize=12;
            writeText(contentStream, font, fontSize, 0, 0, "测试");
            writeText(contentStream, font, fontSize, x+countMM(1), y+move2mm, qz);
            writeText(contentStream, font, fontSize, topTwoTableX+countMM(1), y+move2mm, lb);
            writeText(contentStream, font, fontSize, x+countMM(1), bottomTableY+countMM(3), year);
            if(dep.length()>12) {
                int length1 =dep.length();
                if(length1>18) {
                    length1 =18;
                    String str1=dep.substring(0,length1);
                    writeText(contentStream, font, 8, bottomTwoTableX+countMM(1), bottomTableY+countMM(4), str1);
                    String str2=dep.substring(18);
                    writeText(contentStream, font, 8, bottomTwoTableX+countMM(1), bottomTableY+countMM(1), str2);
                }else {
                    String str1=dep.substring(0,length1);
                    writeText(contentStream, font, 8, bottomTwoTableX+countMM(1), bottomTableY+countMM(4), str1);
                }

            }else {
                writeText(contentStream, font, fontSize, bottomTwoTableX+countMM(1), bottomTableY+countMM(3), dep);
            }
            writeText(contentStream, font, fontSize, bottomThreeTableX+countMM(1), bottomTableY+countMM(3), deadline);
            writeText(contentStream, font, fontSize, bottomFourTableX+countMM(1), bottomTableY+countMM(3), numb);
            contentStream.close();
            doc.save(outPath);
            doc.close();
            return true;
        } catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    private void drawTable(PDPageContentStream contentStream,float x,float y,float tableWidth,float tableHeight){
        try {
            contentStream.setStrokingColor(Color.red);
            drawLine(contentStream,x,y,x,y+tableHeight);
            drawLine(contentStream,x,y+tableHeight,x+tableWidth,y+tableHeight);
            drawLine(contentStream,x+tableWidth,y+tableHeight,x+tableWidth,y);
            drawLine(contentStream,x+tableWidth,y,x,y);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void drawLine(PDPageContentStream contentStream,float startX,float startY,float endX,float endY){
        try {
            contentStream.moveTo(startX,startY);
            contentStream.lineTo(endX,endY);
            contentStream.stroke();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private float countMM(float point){
        return (float) (point*72/25.4);
    }

    private void writeText(PDPageContentStream contentStream, PDFont font, float fontSize, float startX,float startY, String txt) throws IOException {
        if(StringUtils.isEmpty(txt)){
            return;
        }
        contentStream.beginText();
        // 文字位置
        contentStream.newLineAtOffset(startX, startY);
        // 设置字体type,size
        contentStream.setFont(font, fontSize);
        contentStream.setNonStrokingColor(0, 0, 0);
        // 插入文本
        contentStream.showText(txt);
        contentStream.endText();
    }
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
PDFBox是一个用于处理PDF文档的Java库,可以用来读取和写入PDF文档。PDF中的表格通常是由表格框架和单元格组成的。因此,要读取PDF中的表格,我们需要做以下几个步骤: 1. 加载PDF文档 我们可以使用PDFBox库的PDFDocument类来加载PDF文档。示例代码如下: ``` PDDocument document = PDDocument.load(new File("example.pdf")); ``` 2. 遍历文档页面 PDF文档中的表格通常在页面中。我们可以使用PDFBox库的PDFTextStripper类遍历所有页面,并获取页面中的所有文本。示例代码如下: ``` PDFTextStripper stripper = new PDFTextStripper(); for (int i = 1; i <= document.getNumberOfPages(); i++) { stripper.setStartPage(i); stripper.setEndPage(i); String text = stripper.getText(document); // 处理页面文本 } ``` 3. 解析表格 在页面文本中,表格通常是由一系列的单元格组成。我们可以使用正则表达式或其他方法来解析这些单元格,以获取表格内容和结构。示例代码如下: ``` String[] lines = text.split("\\r?\\n"); for (String line : lines) { String[] cells = line.split("\t"); for (String cell : cells) { // 处理单元格内容 } } ``` 4. 关闭文档 在读取完PDF文档后,我们需要关闭它以释放资源。示例代码如下: ``` document.close(); ``` 这些步骤可以帮助我们读取PDF中的表格。但是,请注意,这种方法可能会在复杂的表格结构中出现问题。对于更复杂的表格,我们可能需要使用PDFBox库的其他功能,例如PDF表格提取器(PDFBox Table Extractor)。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值