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

相关推荐
黑客老李1 小时前
BaseCTF scxml 详解
开发语言·网络·数据库·python·sql·安全
m0_748250031 小时前
数据库---HSQLDB使用教程详解
数据库
Karen1982 小时前
汉服文化管理系统|Java|SSM|VUE| 前后端分离
java·数据库·mysql·毕业设计·课程设计
叶 落2 小时前
书籍推荐:MySQL 是怎样运行的-从根上理解 MySQL
数据库·mysql·书籍推荐
五行星辰2 小时前
SQL与数据库交互:Java的财富管理
数据库·sql·交互
大鳥2 小时前
深入了解 StarRocks 表类型:解锁高效数据分析的密码
数据库·starrocks·sql
cooldream20092 小时前
Microsoft Azure Cosmos DB:全球分布式、多模型数据库服务
数据库·人工智能·microsoft·知识图谱·azure
YONG823_API3 小时前
如何通过API实现淘宝商品评论数据抓取?item_review获取淘宝商品评论
大数据·开发语言·javascript·数据库·网络爬虫
华哥啊.3 小时前
redis缓存token失效的处理机制
数据库·redis·缓存
轩轩9902183 小时前
何为“正则表达式”!
数据库·mysql·正则表达式