Java解析PDF数据库设计文档

废话少说,上干货!!!

示例文件:

表1 XXX(XXXXX)表

|----|----|----|------|----|----|----|------|------|
| 名称 | 编码 | 长度 | 数据类型 | 非空 | 主键 | 外键 | 正则校验 | 值域范围 |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |

表2 XXXX表

|----|----|----|------|----|----|----|
| 名称 | 编码 | 长度 | 数据类型 | 非空 | 主键 | 外键 |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |

以上数据库表设计中,如何去解析并打印出具体的内容呢?

直接上程序:

复制代码
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        try (PDDocument document = PDDocument.load(new File("C:\\Users\\AA\\Desktop\\test.pdf"))) {
            PDFTextStripper pdfStripper = new PDFTextStripper();
            String text = pdfStripper.getText(document);
            extractTableInfo(text);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 提取表名称
     *
     * @param text
     * @return
     */
    private static void extractTableInfo(String text) {
        boolean titleStart = false;
        boolean titleEnd = false;
        boolean headStart = false;
        boolean headEnd = false;
        boolean contentStart = false;
        String preTableTile = "";//记录当前表标题名
        StringBuilder tablePreTile = new StringBuilder();//当前的表格标题
        List<String> originList = new ArrayList<>();

        // 按行分割文本
        String[] lines = text.split("\\r?\\n");

        for (String line : lines) {
            line = line.trim();

            //如果一行是纯数字,则可能是解析出的页码,过滤掉
            if (isPureDigit(line)) {
                continue;
            }
            //如果是以GJB或者JB开头,可能是标题,过滤掉
            if (isGJB(line)) {
                continue;
            }

            //--------------------------表名称解析--------------------------
            if ((line.startsWith("表") && line.endsWith("表")) || (line.startsWith("表") && line.length() < 20)) {//标题仅有一行的处理
                titleEnd = true;
                titleStart = false;
                headStart = true;

                if (originList.size() > 0) {
                    reSort(originList);
                    originList = new ArrayList<>();
                }


                tablePreTile.append(line.trim());
                preTableTile = tablePreTile.toString();
                tablePreTile.setLength(0);//标题置空
                System.out.println("【表】" + preTableTile);
                continue;
            }
            if (line.startsWith("表") && line.length() > 20 && (!line.endsWith("表"))) {//如果标题为多行,第一行处理
                titleStart = true;
                tablePreTile.append(line.trim());

                if (originList.size() > 0) {
                    reSort(originList);
                    originList = new ArrayList<>();
                }
                continue;
            }

            if (titleStart && (!titleEnd) && (!line.endsWith("表"))) {//如果标题为多行,中间行(非尾行)处理
                tablePreTile.append(line.trim());
                continue;
            }

            if (titleStart && line.endsWith("表")) {//如果标题为多行,尾行处理
                titleEnd = true;
                titleStart = false;
                headStart = true;
                tablePreTile.append(line.trim());
                preTableTile = tablePreTile.toString();
                tablePreTile.setLength(0);//标题置空
                System.out.println("【表】" + preTableTile);
                continue;
            }

            //--------------------------表格头解析--------------------------
            if (titleEnd && !titleStart && headStart && !titleStart && countSpaces(line) >= 5) {//标题解析结束后,开始解析表头,//普通文字或者其他杂乱字符部分,表内容至少包括:名称、代码、类型、非空、主外键这5个,则直接丢弃
                System.out.println("【表头】" + line);
                headStart = false;
                headEnd = true;
                contentStart = true;
                continue;

            }

            //--------------------------表内容记录--------------------------

            if (!line.trim().equals("")) {//过滤空行
                if (headEnd && !headStart && contentStart) {
                    originList.add(line);
                }
            }


        }

        //针对最后的行处理
        if (originList.size() > 0) {
            reSort(originList);
        }
    }

    /**
     * 对内容进行重新排列
     *
     * @param originList
     */
    private static void reSort(List<String> originList) {
        if (originList.size() > 0) {
            // 定义最大长度 x
        /*    int maxLength = getMaxSplitLength(originList);*/
            // 结果列表
            List<String> result = new ArrayList<>();
            // 遍历字符串列表
            for (int i = 0; i < originList.size(); i++) {
                String current = originList.get(i);
                String[] split = current.split(" ");
                int splitLength = split.length;
                if (splitLength < 6) {//如果按行列宽至少5个字段,如果小于6,则是被分割字段,需要进行拼接重组
                    boolean hasChinese = containsChinese(current);
                    if (hasChinese) {
                        // 向后拼接
                        while (i + 1 < originList.size() && splitLength < 6) {
                            String next = originList.get(++i);
                            current += next; // 向后拼接
                            split = current.split(" ");
                            splitLength = split.length;
                        }
                    } else {
                        // 向前拼接
                        if (i > 0) {
                            String previous = result.remove(result.size() - 1);
                            current = previous + " " + current; // 向前拼接
                        }
                    }
                }
                // 将拼接后的字符串添加到结果列表
                result.add(current);
            }

            // 输出结果
            for (String res : result) {
                System.out.println("【表内容】" + res);
            }
        }
    }

    /**
     * 计算字符串中空格的数量
     *
     * @param str 输入字符串
     * @return 空格数量
     */
    private static int countSpaces(String str) {
        if (str == null) {
            return 0; // 如果字符串为 null,返回 0
        }
        int count = 0;
        for (char c : str.toCharArray()) {
            if (c == ' ') {
                count++;
            }
        }
        return count;
    }

    // 判断字符串是否纯数字
    private static boolean isPureDigit(String line) {
        return line.matches("\\d+");
    }


    // 判断字符串是否纯数字
    private static boolean isGJB(String line) {
        return line.startsWith("GJB") || line.startsWith("JB");
    }

    // 判断字符串是否包含中文
    private static boolean containsChinese(String str) {
        for (char c : str.toCharArray()) {
            if (Character.UnicodeScript.of(c) == Character.UnicodeScript.HAN) {
                return true;
            }
        }
        return false;
    }


    // 计算最大分割长度的函数
    private static int getMaxSplitLength(List<String> strings) {
        int maxLength = 0;

        for (String s : strings) {
            // 按空格分割字符串
            String[] split = s.split(" ");
            // 更新最大长度
            maxLength = Math.max(maxLength, split.length);
        }

        return maxLength;
    }
}

需要用到的JAR包:

pdfbox-2.0.32.jar

相关推荐
伤不起bb22 分钟前
MySQL 高可用
linux·运维·数据库·mysql·安全·高可用
Yushan Bai5 小时前
ORACLE RAC环境REDO日志量突然增加的分析
数据库·oracle
躺着听Jay5 小时前
Oracle-相关笔记
数据库·笔记·oracle
瀚高PG实验室6 小时前
连接指定数据库时提示not currently accepting connections
运维·数据库
运维成长记7 小时前
mysql数据库-中间件MyCat
数据库·mysql·中间件
尘客.7 小时前
DataX从Mysql导数据到Hive分区表案例
数据库·hive·mysql
大强同学7 小时前
Adobe DC 2025安装教程
windows·adobe·pdf
TiDB 社区干货传送门8 小时前
从开发者角度看数据库架构进化史:JDBC - 中间件 - TiDB
数据库·oracle·中间件·tidb·数据库架构
虾球xz8 小时前
游戏引擎学习第280天:精简化的流式实体sim
数据库·c++·学习·游戏引擎
uwvwko9 小时前
BUUCTF——web刷题第一页题解
android·前端·数据库·php·web·ctf