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

相关推荐
betazhou7 分钟前
sqlserver2017 分离附加数据库
数据库·oracle·sqlserver
我是小木鱼11 分钟前
浅析Centos7安装Oracle12数据库
linux·运维·服务器·数据库
Arbori_2621514 分钟前
oracle 表空间(Tablespace)
数据库·oracle
茉莉玫瑰花茶41 分钟前
线程同步与互斥(下)
linux·数据库
BUG 劝退师1 小时前
MySQL数据库编程总结
数据库·mysql
notfindjob1 小时前
QT Sqlite数据库-教程001 创建数据库和表-上
数据库
亚林瓜子1 小时前
docker compose方式安装ClickHouse数据库
数据库·clickhouse·docker·mac·m1
04Koi.1 小时前
Redis进阶--哨兵
数据库·redis·缓存
小蒜学长2 小时前
机动车号牌管理系统设计与实现(代码+数据库+LW)
开发语言·数据库·spring boot·后端·spring·oracle
随缘而动,随遇而安2 小时前
第四十六篇 人力资源管理数据仓库架构设计与高阶实践
大数据·数据库·数据仓库·sql·数据库架构