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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949275.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity 3D游戏开发从入门进阶到高级

本文精心整理了Unity3D游戏开发相关的学习资料&#xff0c;涵盖入门、进阶、性能优化、面试和书籍等多个维度&#xff0c;旨在为Unity开发者提供全方位、高含金量的学习指南.欢迎收藏。 学习社区 Unity3D开发者 这是一个专注于Unity引擎的开发者社区&#xff0c;汇聚了众多Un…

Python 21:Debug

1. Debug的作用 当程序的预期结果和实际结果不一致时&#xff0c;可以用Debug模式进行调试来定位问题的位置。 2. Debug使用 1&#xff09;设置断点 点击行号&#xff0c;出现”断点“ 2&#xff09;执行Debug 点击Debug 或者右键&#xff0c;点击debug进入debug模式 3.Debu…

(CICD)自动化构建打包、部署(Jenkins + maven+ gitlab+tomcat)

一、平滑发布与灰度发布 **什么叫平滑&#xff1a;**在发布的过程中不影响用户的使用&#xff0c;系统不会因发布而暂停对外服务&#xff0c;不会造成用户短暂性无法访问&#xff1b; **什么叫灰度&#xff1a;**发布后让部分用户使用新版本&#xff0c;其它用户使用旧版本&am…

强化学习入门谈

之前我们见识到很多机器学习大展手脚的任务场景了&#xff0c;但是机器学习依旧有很多软肋。 回忆一下&#xff0c;我们之前做的机器学习&#xff08;深度学习&#xff09;策略基本都是类似于"supervised learning"的方法&#xff0c;比如你想用CNN实现一个classifi…

colnames看似简单,却能优化数据处理流程

引言 在数据处理和分析中&#xff0c;变量名称是至关重要的&#xff0c;它们决定了数据的可读性和操作的简便性。在R语言中&#xff0c;colnames 函数以其简单的语法设计&#xff0c;提供了高效管理数据框列名的能力&#xff0c;尤其是在复杂的爬虫任务中显得尤为重要。本篇文…

【分布式】Hadoop完全分布式的搭建(零基础)

Hadoop完全分布式的搭建 环境准备&#xff1a; &#xff08;1&#xff09;VMware Workstation Pro17&#xff08;其他也可&#xff09; &#xff08;2&#xff09;Centos7 &#xff08;3&#xff09;FinalShell &#xff08;一&#xff09;模型机配置 0****&#xff09;安…

ArcGIS中怎么把数据提取到指定范围(裁剪、掩膜提取)

最近&#xff0c;经常能收到怎么把数据提取到指定范围、栅格数据怎么裁剪、矢量数据怎么裁剪、栅格数据怎么掩膜提取的咨询。 下面是我对这个问题的解决思路&#xff1a; 对于矢量数据&#xff1a; ①首先把数据加载进来 ②软件界面上面的工具栏找到→地理处理→裁剪&#x…

intra-mart环境搭建笔记

一、前言 最近在做intra-mart项目&#xff0c;网上这些笔记比较少&#xff0c;在此做一下笔记。 intra-mart是由日本intra-mart公司开发和销售的工作流平台&#xff0c;国内确实不怎么用&#xff0c;日本企业用的多些&#xff0c;面试时会问有没有intra-mart经验。 这个自学…

智能型电瓶车充电桩在老居民区充电站中的应用优势

摘要 随着电瓶车数量的快速增长&#xff0c;小区内的电瓶车充电需求日益增加&#xff0c;但传统充电方式存在诸多安全隐患。电瓶车智能充电桩作为一种新型充电解决方案&#xff0c;能够有效解决充电难题&#xff0c;并提升充电安全性和便捷性。本文以ACX10A型电瓶车充电桩为…

生产看板真的有用吗?

​看板&#xff0c;对于从事制造行业的人员来说&#xff0c;这并不陌生。但是对于看板起到的作用&#xff0c;那可就是众说纷纭&#xff0c;有人说&#xff0c;看板是领导的“面子工程”&#xff0c;是混淆上级视察的工具&#xff1b;也有人说&#xff0c;看板真切地帮助车间提…

刷服务器固件

猫眼淘票票 大麦 一 H3C通用IP 注:算力服务器不需要存储 二 刷服务器固件 1 登录固定IP地址 2 升级BMC版本 注 虽然IP不一致但是步骤是一致的 3 此时服务器会出现断网现象&#xff0c;若不断网等上三分钟ping一下 4 重新登录 5 断电拔电源线重新登录查看是否登录成功

机器学习算法在推荐系统中的应用:从数据预处理到模型部署实战指南

机器学习算法在推荐系统中的应用&#xff1a;从数据预处理到模型部署实战指南 介绍 在当今信息爆炸的时代&#xff0c;推荐系统扮演了越来越重要的角色&#xff0c;它可以帮助用户发现和获取个性化的信息、产品或服务。而推荐系统中的机器学习算法则是其核心引擎&#xff0c;能…

上门按摩系统架构与功能分析

一、系统架构 服务端用Java语言&#xff08;最低JDK1.8&#xff0c;支持JDK11以及JDK17&#xff09;、MySQL数据库&#xff08;标配5.7版本&#xff0c;支持MySQL8&#xff09;&#xff0c;Mybatis ORM框架&#xff0c;Redis缓存&#xff0c;nginx代理&#xff0c;前端用uniap…

使用mne对运动想象数据bciIV进行预处理

需要的库 mne numpy scipy scikit-learn pip install mne numpy scipy scikit-learn 数据下载 对Data sets 2a ‹4-class motor imagery› 四分类的运动想象来进行mne的处理。 BCI Competition IV 数据的说明如下 [22 EEG channels (0.5-100Hz; notch filtered), 3 EOG chann…

设计模式 行为型 策略模式(Strategy Pattern)与 常见技术框架应用 解析

策略模式&#xff08;Strategy Pattern&#xff09;核心思想是将算法的实现从使用该算法的类中分离出来&#xff0c;作为独立的对象&#xff0c;通过接口来定义算法家族&#xff0c;这样就可以很容易地改变或扩展算法。通过这种方式&#xff0c;可以避免在客户端代码中使用大量…

配置管理工具和k8s功能重叠部分的优势比较

通过自动化配置管理工具&#xff08;如 Ansible、Puppet、Chef&#xff09;和应用内管理机制&#xff0c;也可以实现自动部署、扩缩容、负载均衡和故障恢复等功能。Kubernetes&#xff08;K8s&#xff09;在这些方面具有哪些独特的优势呢&#xff0c;尤其是在云原生环境和大规模…

OpenHarmony AVScreenCaptureRecorder录屏开发指导

一、简介 OpenHarmony 5.0新增了AVScreenCaptureRecorder ArkTs API。用户可以调用录屏AVScreenCaptureRecorder API录制屏幕&#xff0c;采集音频源数据&#xff0c;获取封装后的音视频文件&#xff0c;然后通过文件的形式流转到其他模块进行播放或处理&#xff0c;用于以文件…

CSS Grid 布局示例(基本布局+代码属性描述)

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>CSS Grid 布局示例</title><style>.gri…

爬虫学习案例3

爬取美女图片 优美图库地址 一页图片 安装依赖库文件 pip install selenium requests beautifulsoup4import time import requests import random from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.service import Service fr…

简单的spring boot tomcat版本升级

简单的spring boot tomcat版本升级 1. 需求 我们使用的springboot版本为2.3.8.RELEASE&#xff0c;对应的tomcat版本为9.0.41&#xff0c;公司tomcat对应版本发现攻击者可发送不完整的POST请求触发错误响应&#xff0c;从而可能导致获取其他用户先前请求的数据&#xff0c;造…