精华内容
下载资源
问答
  • Excel如何提取单元格部分文字或单元格的数字 Excel如何提取单元格部分文字或单元格的数字,整理了Excel所有的提取要求,写成了一个公式翻译工具。 支持以下提取方式,输入提取要求,自动生成Excel...

          Excel如何提取单元格中的部分文字或单元格中的数字

    Excel如何提取单元格中的部分文字或单元格中的数字,整理了Excel中所有的提取要求,写成了一个公式翻译工具。

    支持以下提取方式,输入提取要求,自动生成Excel公式:

    A2中的前几个字

    A2中的后几个字

    A2中的"年"之前的内容

    A2中的"月"之后的内容

    A2中的"年"字到"月"字之间的内容

    A2中的第2个"-"到第3个"-"之间的内容

    A2中的第1组整数

    A2中的第2组浮点数

    A2中的第1个"-"之前的内容 & A2中的第1个"-"到第2个"-"之间的内容& A2中的第2个"-"到第3个"-"之间的内容  

          (注意:& 表示文字组合,例如  “A”&“,”&"B" = A,B)

    等等....

    工具地址:www.excelfb.com  

    点击: Excel自动写公式工具(根据汉字描述写公式,支持合并单元格公式)

    点击: 提取单元格内文字中的内容(数字,"x"字与"x"字之间的内容,第几个"x"之前的内容)

    操作方式如下图:

    示例一,提取第几组浮点数,提取单元格中数字

    示例二,提取 第几个"-"到第几个"-"之间的内容:

    示例三,提取 前几位

    Ctrl + C,复制公式使用即可。

     

      &表示文字相加

    工具地址:www.excelfb.com  

    点击: Excel自动写公式工具(根据汉字描述写公式,支持合并单元格公式)

    点击: 提取单元格内文字中的内容(数字,"x"字与"x"字之间的内容,第几个"x"之前的内容)

     

     

     

     

     

     

    展开全文
  • 怎么提取pdf表格数据In this article, we talk about the challenges and principles of extracting tabular data from PDF docs. We also compare six software tools to find out how they perform their ...

    怎么提取pdf中的表格数据

    In this article, we talk about the challenges and principles of extracting tabular data from PDF docs. We also compare six software tools to find out how they perform their respective tasks of parsing PDF tables and getting data out of them.

    在本文中,我们讨论了从PDF文档中提取表格数据的挑战和原理。 我们还比较了六个软件工具,以了解它们如何执行各自的任务以解析PDF表并从中获取数据。

    为什么从PDF中提取表格数据是一个挑战 (Why It’s a Challenge to Extract Tabular Data from PDF)

    Today PDF is used as the basis of communication between companies, systems, and individuals. It is regarded as the standard for finalized versions of documents as it is not easily editable except in fillable PDF forms. Most popular use cases for PDF documents in the business environment are:

    今天,PDF用作公司,系统和个人之间进行交流的基础。 它被认为是文档定稿版本的标准,因为除了可填写的PDF表格外,它不容易编辑。 在业务环境中,PDF文档的最流行用例是:

    • Invoices

      发票
    • Purchase Orders

      订单
    • Shipping Notes

      运输注意事项
    • Reports

      报告书
    • Presentations

      简报
    • Price & Product Lists

      价格和产品清单
    • HR Forms

      人力资源表格

    The sheer volume of information exchanged in PDF files means that the ability to extract data from PDF files quickly and automatically is essential. Spending time extracting data from PDFs to input into third party systems can be very costly for a company.

    PDF文件中大量的信息交换意味着快速,自动地从PDF文件提取数据的能力至关重要。 花费时间从PDF提取数据以输入到第三方系统对于公司而言可能是非常昂贵的。

    The main problem is that PDF was never really designed as a data input format, but rather, it was designed as an output format ensuring that data will look the same at any device and be printed correctly. A PDF file defines instructions to place characters (and other components) at precise x,y coordinates. Words are simulated by placing some characters closer than others. Spaces are simulated by placing words relatively far apart. As for tables — you are right — they are simulated by placing words as they would appear in a spreadsheet.

    主要问题是PDF从来没有真正设计成数据输入格式,而是设计成输出格式,以确保数据在任何设备上看起来都一样并且可以正确打印。 PDF文件定义了将字符(和其他组件)放置在精确的x,y坐标处的指令。 通过将某些字符放置得比其他字符更近来模拟单词。 通过将单词相对分开放置来模拟空间。 至于表,您是对的,它们是通过像在电子表格中一样放置单词来模拟它们的。

    We see that the PDF format has no internal representation of a table structure, which makes it difficult to extract tables for analysis. Unfortunately, a lot of open data is stored in PDFs, which was not designed for tabular data in the first place.

    我们看到PDF格式没有表结构的内部表示,这使得提取表进行分析变得很困难。 不幸的是,许多开放数据存储在PDF中,而这些数据最初并不是为表格数据而设计的。

    Luckily, different tools for extracting data from PDF tables are available in the market. Being somewhat similar to each other, they have their own advantages and disadvantages. In this article, we compare the most popular software that can help get tabular data out of PDFs and present it in an easy-to-read, editable, and searchable format.

    幸运的是,市场上有多种用于从PDF表提取数据的工具。 它们彼此有点相似,但各有优缺点。 在本文中,我们将比较最流行的软件,该软件可以帮助从PDF中获取表格数据,并以易于阅读,可编辑和可搜索的格式显示它们。

    OCR:何时以及为什么使用它 (OCR: When and Why to Use It)

    Before choosing a tool, the first point is to understand what type of PDF files — text- or image-based — you will work with. It will impact on whether to use Optical Character Recognition (OCR) or not.

    在选择工具之前,首先要了解您将使用哪种类型的PDF文件(基于文本或图像)。 这将影响是否使用光学字符识别(OCR)。

    For example, we have a report generated as an output by a piece of software and imported in PDF format. Commonly, it is a text-based PDF.

    例如,我们有一个报告,它是由一个软件生成的输出,并以PDF格式导入。 通常,它是基于文本的PDF。

    If you work with image-based PDFs like scanned paper docs, or, for example, files captured by a digital camera — this is where OCR comes in. OCR enables machines to recognize written text or printed letters inside images. In other words, the technology helps to convert ‘text-as-an-image’ into an editable and searchable format.

    如果您使用基于图像的PDF(例如,扫描的纸张文档),或者使用数码相机捕获的文件,则可以使用OCR。OCR使机器可以识别图像中的文字或印刷字母。 换句话说,该技术有助于将“文本图像”转换为可编辑和可搜索的格式。

    Image for post
    Document scanned and converted into a text document using OCR
    使用OCR扫描文档并将其转换为文本文档

    o if your PDF is image-based, then the process of data extraction consists of two tasks: to recognize text and then recognize the table structure (i.e., how the text is placed in rows and columns). Some tools, like Amazon Textract, can complete both of them. But since text recognition is a separate task, it can be performed independently, with the help of pure OCR tools. There are dozens of them, but in this article, we will focus on the table structure recognition.

    o如果您的PDF是基于图像的,则数据提取过程包括两个任务:识别文本,然后识别表结构(即,文本在行和列中的放置方式)。 某些工具(例如Amazon Textract)可以完成这两个工具。 但由于文本识别是一项单独的任务,因此可以在纯OCR工具的帮助下独立执行。 它们有数十种,但是在本文中,我们将重点放在表结构识别上。

    从表中检测和提取数据的细节 (Nuances of Detecting and Extracting Data from Tables)

    Let’s assume that we have a text-based PDF document generated as an output by a piece of software. It contains tabular data, and we want to extract it and present in a digital format. There are two main ways to detect tables:

    假设我们有一个基于文本的PDF文档,它是由一个软件生成的输出。 它包含表格数据,我们希望将其提取并以数字格式显示。 检测表有两种主要方法:

    • Manually, when you detect column borders by eye and mark table columns by hands

      手动,当您用肉眼检测列边界并用手标记表格列时
    • Automatically, when you rely on program algorithms

      自动,当您依赖程序算法时

    Some tools offer either manual or automatic detection, while others combine both variants. From our experience, we can say that most of our clients’ cases require automatic recognition because they handle hundreds of documents with a slightly variable table structure. For example, columns’ width can differ not only between two documents but also on different pages inside one document. Therefore, if we mark each column in each table on each page by hand, it would take a lot of time and effort.

    一些工具提供手动或自动检测,而其他工具则结合了这两种变体。 根据我们的经验,我们可以说大多数客户的案例需要自动识别,因为他们处理的表结构略有变化的数百个文档。 例如,列的宽度不仅可以在两个文档之间不同,而且可以在一个文档内的不同页面上不同。 因此,如果我们在每个页面上手动标记每个表中的每一列,则将花费大量时间和精力。

    For our study, we created a sample one-page document covering all typical difficulties of data extraction caused by an ‘inconsistent’ table structure. Here is it:

    对于我们的研究,我们创建了一个样本的单页文档,其中涵盖了由“不一致”表结构引起的所有典型数据提取困难。 就这个:

    Image for post
    Sample document created for the study
    为研究创建的样本文件

    As you can see, in our sample document, we have multiple tables, and all of them have different widths of columns and inconsistent alignments. In such cases, manual detection can be tedious. For this reason, we are not going to use software that offers only manual table data detection. We choose an automatic way, and let’s see how good are algorithms for each of the tools.

    如您所见,在我们的示例文档中,我们有多个表,并且所有表都有不同的列宽和不一致的对齐方式。 在这种情况下,手动检测可能很乏味。 因此,我们将不使用仅提供手动表格数据检测的软件。 我们选择一种自动方式,让我们看看每种工具的算法效果如何。

    In addition to the table structure’s basic elements, we also deliberately included some ‘extra formatting’ that can potentially complicate the process of recognition:

    除了表结构的基本元素外,我们还故意包含一些“额外格式”,这些格式可能会使识别过程复杂化:

    • Multiple tables on a page — all of them should be detected

      页面上有多个表格-应该检测到所有这些表格
    • Non-tabular data: headers and page number

      非表格数据:标题和页码
    • The multiline text inside cells

      单元格内的多行文字
    • Table column & row spanning — merged cells

      表的列和行跨度—合并的单元格
    • Small table cell margins inside the table and between the table and the header

      表格内部以及表格和标题之间的小表格单元格边距

    PDF表提取库和工具的比较 (Comparison of PDF Table Extraction Libraries and Tools)

    From this study, you will learn about how six software tools perform their respective tasks of parsing PDF tables and how they stack up against each other. In the first part, we compare Tabula, PDFTron, and Amazon Textract.

    通过本研究,您将了解六个软件工具如何执行各自的解析PDF表的任务,以及它们如何相互堆叠。 在第一部分中,我们比较了Tabula,PDFTronAmazon Textract。

    Let’s see how libraries and tools mentioned above coped with this task of data recognition and extraction based on our sample document.

    让我们看看上面提到的库和工具如何根据我们的示例文档来完成数据识别和提取的任务。

    塔布拉 (Tabula)

    Tabula is a tool for liberating data tables locked inside PDF files. Tool overview:

    Tabula是用于释放锁定在PDF文件中的数据表的工具。 工具概述:

    • Type of software available: web application, requires simple local server setup

      可用软件类型: Web应用程序,需要简单的本地服务器设置

    • Platforms: Windows, MacOS, open source (GitHub, MIT Licence)

      平台: Windows,MacOS,开源(GitHub,MIT Licence)

    • Terms of use: free, open-source

      使用条款:免费,开源

    • Supported output formats: CSV, TSV, JSON

      支持的输出格式: CSV,TSV,JSON

    • Notes: Tabula only works on text-based PDFs, not scanned documents

      注意: Tabula仅适用于基于文本的PDF,不适用于扫描的文档

    After uploading our sample file and parsing data from it via Tabula, we got the following output:

    在上传示例文件并通过Tabula解析其中的数据之后,我们得到以下输出:

    Image for post
    Image for post
    Tabula: the result of detection of tables in the sample document
    表格:示例文档中表格的检测结果

    Zones marked in red are parts of the original file where Tabula detected tables. At this step, data recognition is captured correctly; all tables are detected, extraneous elements do not distort the result.

    红色标记的区域是Tabula检测到表的原始文件的一部分。 在此步骤中,数据识别已正确捕获。 所有表都被检测到,无关元素不会扭曲结果。

    But if we go further, we will see that the first row of the first and last rows of the last two tables is missing:

    但是,如果走得更远,我们将看到最后两个表的第一行和最后一行的第一行丢失了:

    Image for post
    Tabula’s Lattice method: preview of extracted tabular data
    Tabula的Lattice方法:预览提取的表格数据

    Tabula offers two options: two data extraction methods. The automatic detection method is Lattice. The result of its usage you can see above. If we try Stream, results become better; all data is extracted correctly without missing rows:

    Tabula提供了两种选择:两种数据提取方法。 自动检测方法是莱迪思。 您可以在上面看到其使用结果。 如果尝试Stream ,结果会更好; 正确提取所有数据而不会丢失行:

    Image for post
    Tabula’s Stream method: preview of extracted tabular data
    Tabula的Stream方法:预览提取的表格数据

    But using the Stream method, we face another problem: cells with multiline text are split into multiple table rows. It seems this variant is the best that we can get from Tabula.

    但是使用Stream方法,我们面临另一个问题:具有多行文本的单元格被拆分为多个表行。 看来这种变形是我们可以从Tabula获得的最好的变形。

    Summary: Tabula’s automatic detection method is not the best choice, so I don’t recommend relying on it. Both recognition methods provided by this tool have their own disadvantages. While data loss looks unacceptable in any case, split rows can be returned to their original state with additional processing — manually or with the script’s help.

    简介 :Tabula的自动检测方法不是最佳选择,因此我不建议依赖它。 此工具提供的两种识别方法都有其自身的缺点。 尽管在任何情况下数据丢失看起来都是不可接受的,但可以通过手动或在脚本的帮助下进行额外的处理,将拆分的行恢复为原始状态。

    PDFTron (PDFTron)

    PDFTron is software with multiple basic and advanced features that facilitate the manipulation of PDFs. Tool overview:

    PDFTron是具有多种基本和高级功能的软件,可简化对PDF的操作。 工具概述:

    • Type of software available: desktop app, web browser app, mobile app

      可用软件类型:桌面应用程序,Web浏览器应用程序,移动应用程序
    • Platforms: Android, iOS, Windows, Linux, MacOS

      平台:Android,iOS,Windows,Linux,MacOS
    • Terms of use: free trial period, pricing for licensing starts at $4000 annually

      使用条款:免费试用期,许可的起价为每年4000美元
    • Supported output formats: MS Word, SVG, HTML

      支持的输出格式:MS Word,SVG,HTML

    After uploading our sample file and parsing data from it via PDFTron, we got the following output:

    在上传示例文件并通过PDFTron解析了其中的数据之后,我们得到以下输出:

    Image for post
    PDFTron: the result of detection of tables in the sample document
    PDFTron:样本文档中表格的检测结果

    Red rectangles show the borders of detected tables. The number of tables and tabular data is recognized correctly, but headers of the third and fourth tables are captured as the table elements.

    红色矩形显示检测到的表格的边框。 可以正确识别表和表格数据的数量,但是将第三和第四表的标题捕获为表元素。

    If we convert the original PDF into HTML format using PDFTron, we’ll see that the headers named ‘CATEGORY 2’ and ‘CATEGORY 3’ are included as separate cells inside the table. Also, there are bugs with merged cells of the first table: the last two columns are merged as a larger one, and the second line of text is separated into a separate cell.

    如果使用PDFTron将原始PDF转换为HTML格式,则会看到名为“ CATEGORY 2”和“ CATEGORY 3”的标头作为单独的单元格包含在表中。 此外,第一个表的合并单元格也存在错误:最后两列合并为较大的单元格,第二行文本被分隔为单独的单元格。

    Image for post
    PDFTron: preview of extracted tabular data
    PDFTron:预览表格数据的预览

    Summary: In the output document we can see a piece of non-tabular data incorrectly included in the extraction result. It’s not a big problem since it can be purged after processing, manually, or with the script’s help. Also, I will not recommend this tool in cases when you have a lot of merged cells — they might be messed up.

    简介:在输出文档中,我们可以看到提取结果中错误地包含了一段非表格数据。 这不是一个大问题,因为可以在处理后,手动或在脚本的帮助下清除它。 另外,如果您有很多合并的单元格,则我不推荐使用此工具,因为它们可能会弄糟。

    亚马逊Textract (Amazon Textract)

    Amazon Textract is a service that automatically extracts text and data from scanned documents that go beyond simple optical character recognition (OCR) to identify, understand, and extract data from forms and tables. Tool overview:

    Amazon Textract是一项服务,可以自动从扫描的文档中提取文本和数据,而不仅仅是简单的光学字符识别(OCR)来识别,理解和提取表单和表格中的数据。 工具概述:

    • Type of software available: web application

      可用软件类型:Web应用程序
    • Platforms: any modern web browser, all processing goes ‘in the Cloud’

      平台:任何现代的Web浏览器,所有处理都在“云端”进行
    • Terms of use: several models (free, monthly subscriptions, cost-per-page model)

      使用条款:多种模式(免费,每月订阅,每页成本模式)
    • Supported output formats: raw JSON, JSON for each page in the document, text, key/values exported as CSV, tables exported as CSV.

      支持的输出格式:原始JSON,文档中每个页面的JSON,文本,以CSV格式导出的键/值,以CSV格式导出的表。

    After uploading our sample file and parsing data from it via Amazon Textract, we got the following result:

    在上传示例文件并通过Amazon Textract解析了其中的数据之后,我们得到了以下结果:

    Image for post
    Image for post
    Amazon Textract: the result of detection of tables in the sample document
    Amazon Textract:示例文档中表的检测结果

    Zones painted in gray are parts of the original file where Amazon Textract detected tables. As you can see, it didn’t recognize the first table on the page, detected two separate tables — the second and the third — as a single one, and also messed up the order of tables on the page.

    灰色区域是Amazon Textract检测到表的原始文件的一部分。 如您所见,它无法识别页面上的第一个表,将两个单独的表(第二个和第三个表)检测为单个表,并且还弄乱了页面上表的顺序。

    Regarding the data inside the cells, the extraction result is quite satisfying with some exceptions:

    关于单元内的数据,提取结果非常令人满意,但有一些例外:

    • Missing the data of the first table in the extraction result

      提取结果中缺少第一个表的数据
    • Header string ‘CATEGORY 3 is included as a part of table in the extraction result

      标头字符串“ CATEGORY 3”作为表的一部分包含在提取结果中
    Image for post
    Image for post
    Amazon Textract: preview of extracted tabular data
    Amazon Textract:预览表格数据的预览

    Summary: Amazon Textract looks to be the less suitable tool for data extraction applied to this particular case. A large amount of data loss, messed order of tables, and non-tabular data in the output document. The main advantage of Amazon Textract compared to all other tools is OCR, so that you can extract tabular data from images or image-based PDFs. In the case of text-based PDF, I would recommend choosing another tool.

    简介: Amazon Textract似乎不太适合应用于此特定案例的数据提取工具。 输出文档中大量数据丢失,表顺序混乱以及非表格数据。 与所有其他工具相比,Amazon Textract的主要优势是OCR,因此您可以从图像或基于图像的PDF中提取表格数据。 对于基于文本的PDF,我建议选择其他工具。

    Here is the first part of the article ‘How to Extract Tabular Data from PDF. In the second part, which is coming soon, we will analyze three more popular solutions for extracting and converting data from PDF and prepare a big сomparison table where each tool is rated according to the specific criteria. Follow UpsilonIT’s blog not to miss the great content!

    这是文章“如何从PDF提取表格数据”的第一部分。 即将推出 的第二部分中 ,我们将分析另外三种从PDF提取和转换数据的流行解决方案,并准备 一张巨大的比较表 ,其中每个工具均根据特定标准进行评级。 关注UpsilonIT的博客,不要错过精彩的内容!

    翻译自: https://medium.com/@upsilon_it/how-to-extract-tabular-data-from-pdf-part-1-16cc3a29fcfa

    怎么提取pdf中的表格数据

    展开全文
  • 在word存在多个表格,每个表格会有一些使用不同颜色标注的高亮文本,那么如何利用编程语言自动的提出这些高亮文本呢?这便是本文的问题情境,针对此,我使用Java实现了这一功能。 针对上面,这个表格(只匹配表格...


    Email:1563178220@qq.com 内容可能有不到之处,欢迎交流。

    未经本人允许禁止转载

    问题情境

    在word中存在多个表格,每个表格会有一些使用不同颜色标注的高亮文本,那么如何利用编程语言自动的提出这些高亮文本呢?这便是本文的问题情境,针对此,我使用Java实现了这一功能。
    在这里插入图片描述

    针对上面,这个表格(只匹配表格中的红色、黄色、蓝色、绿色对应的文本),Java程序的输出结果为:
    在这里插入图片描述
    处理时,这里不考虑表格的表头。

    相关jar包

    使用maven可以配置相关jar包,具体如下:

    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi</artifactId>
    			<version>3.17</version>
    		</dependency>
    
    		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml</artifactId>
    			<version>3.17</version>
    		</dependency>
    

    同时,还需要下载poi-scratchpad-3.17.jar:

    在这里插入图片描述

    Java实现程序

    package com.qian.word;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    
    public class WordRead {
    	public static void main(String[] args) throws IOException {
    		//设置要匹配的颜色--16进制颜色代码
    		String[] colors = {"FF0000", //红色
    				"FFFF00", //黄色
    				"0000FF", //蓝色
    				"00FF00" //绿色
    				};
    		
    		InputStream in = new FileInputStream("data/wordtext.docx"); //docx文件
    		@SuppressWarnings("resource")
    		XWPFDocument xdoc = new XWPFDocument(in);
    		Iterator<XWPFTable> itTable = xdoc.getTablesIterator();  //获取word文件中的表格
    		XWPFTable table;
    		int tableIndex = 0; //表格编号
    		System.out.println("表格编号" + "\t" +  "行" + "\t" + "列" + "\t" + "文本" + "\t" + "高亮颜色"  + "\t");
    		while (itTable.hasNext()) {  //循环word中的每个表格
    			tableIndex++;
    			table = itTable.next();
    			XWPFTableRow row;
    			List<XWPFTableCell> cells;
    			for (int i = 0; i < table.getNumberOfRows(); i++) {
    				if(i == 0)  //这里设置是否包含表头
    					continue;
    				row = table.getRow(i);  //获取word表格的每一行
    				cells = row.getTableCells();  //针对每一行的所有单元格
    				for (int j = 0; j < cells.size(); j++) {
    					XWPFTableCell cell = cells.get(j); //获取单个单元格
    					//获取单元格相同字体颜色+文字
    					XWPFParagraph paras = cell.getParagraphs().get(0); //获取包含段落的列表--只有一段
    					List<XWPFRun> runsLists = paras.getRuns();//获取段落中的列表
    					for(XWPFRun xL:runsLists){
    						String c = xL.getColor(); 
    						String text = xL.text(); 
    						if (c!=null&&Arrays.asList(colors).contains(c)) {
    							System.out.println(tableIndex + "\t" + i + "\t" + j + "\t" + text + "\t" + c  + "\t");
    						}
    					}
    				}
    			}
    		}
    	}
    }
    
    
    展开全文
  • 对于word的数据,我们可能存在将其抽取为结构化数据的需求。抽取思想为对整个word文档上至下扫描,并对其中的文字表格进行区分处理,可以记录文字表格的顺序,并自由选择是否抽取出表格中文字

    目的

    对于word中的数据,我们可能存在将其抽取为结构化数据的需求。

    好处

    • 将数据存储于数据库中,将数据从word繁杂的以手工编辑的格式媒介中抽离出来,便于做大数据分析、ai数据集准备等后续操作。
    • 提供在网页等其它媒介中方便地展示、编辑、再储存等,可自由定制数据展示方式,而不需依赖word客户端组件。

    概述及依赖

    Word包括docx和doc,其中doc源文件为二进制流文件,可读性较差。docx为xml文件,可读性较强。
    想要使用全套的poi解析word,引用的maven包如下:

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>1.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>2.6.0</version>
    </dependency>
    

    相信我,使用这套引用没有问题,特别全!甚至你版本号也不需要改!如果你需要改动版本号,还需要注意不同包之间的版本关系。具体查看网址如下:
    Maven Repository: org.apache.poi » poi
    进入这个网址后点击对应版本号往下拉可以看到对应依赖版本配置,以保证没有依赖错误。

    开始

    在poi中,doc与docx使用的是完全不同的类,方法内部逻辑也不相同,需要各自开发。
    docx主要使用的类:XWPFDocument(WordExtractor类是其子集,不需要它),相关规范
    doc主要使用的类:HWPFDocument

    抽取

    核心思想:

    对整个word文档从上至下扫描,并对其中的文字和表格进行区分处理,优点:

    • 可以记录文字和表格的顺序,而其它网站上的抽取方法很可能会丢失页面文字和表格的顺序。
    • 其它网站的方法很可能在抽文字时会把表格中的文字一并抽出,而我这里可以自由选择是否抽取出表格中的文字。

    常量定义

    /**
     * word表格默认高度
     */
    private static final int DEFAULT_HEIGHT = 500;
    
    /**
     * word表格默认宽度
     */
    private static final int DEFAULT_WIDTH = 1000;
    
    /**
     * word表格转换参数 默认为/1 可以根据需求调整
     */
    private static final int DEFAULT_DIV = 1;
    
    /**
     * 目前没有提取word的字体大小 默认为12
     */
    private static final Float DEFAULT_FONT_SIZE = 12.0F;
    
    /**
     * word的全角空格 以及\t 制表符
     */
    private static final String WORD_BLANK = "[\u00a0|\u3000|\u0020|\b|\t]";
    
    /**
     * word的它自己造换行符 要换成string的换行符
     */
    private static final String WORD_LINE_BREAK = "[\u000B|\r]";
    
    /**
     * word table中的换行符和空格
     */
    private static final String WORD_TABLE_FILTER = "[\\t|\\n|\\r|\\s+| +]";
    
    /**
     * 计算表格行列信息时设置的偏移值
     */
    private static final Float TABLE_EXCURSION = 5F;
    
    /**
     * 抽取文字时去掉不必须字符正则
     */
    private static final String splitter = "[\\t|\\n|\\r|\\s+|\u00a0+]";
    
    private static final String regexClearBeginBlank = "^" + splitter + "*|" + splitter + "*$";
    

    结构化javabean类:

    WordTableCell类:

    @Data
    public class WordTableCell {
    
        private Float x;
    
        private Float y;
    
        private Float width;
    
        private Float height;
    
        private String text;
    
        /**
         * 默认为12
         */
        private Float fontSize;
    
        /**
         * 行号 0开始
         */
        private Integer row;
    
        /**
         * 列号 0开始
         */
        private Integer col;
    
        /**
         * 行跨度 从1开始
         */
        private Integer rowspan;
    
        /**
         * 列跨度 从1开始
         */
        private Integer colspan;
    }
    

    WordTable类:

    @Data
    public class WordTable {
        
        private List<WordTableCell> wordTableCellList;
        
        private Float width;
        
        private Float height;
    }
    

    WordContent类(包括word抽取出的文字和表格结构)

    @Data
    public class WordContent {
    
        /**
         * text包括段落文字(不包括表格文字,改成包括表格文字也很简单)
         */
        private String text;
    
        /**
         * 抽取的表格对象
         */
        private List<WordTable> wordTableList;
    }
    

    docx核心方法解析:

    1. 概述:
      每个docx中都对应着一个xml文件,样式示例如下:
    					<w:tbl>
    						<w:tblPr>
    							<w:tblStyle w:val="3"/>
    							<w:tblW w:type="auto" w:w="0"/>
    							<w:jc w:val="center"/>
    							<w:tblBorders>
    								<w:top w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    								<w:left w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    								<w:bottom w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    								<w:right w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    								<w:insideH w:color="auto" w:space="0" w:sz="4" w:val="single"/>
    								<w:insideV w:color="auto" w:space="0" w:sz="4" w:val="single"/>
    							</w:tblBorders>
    							<w:tblLayout w:type="fixed"/>
    							<w:tblCellMar>
    								<w:top w:type="dxa" w:w="0"/>
    								<w:left w:type="dxa" w:w="108"/>
    								<w:bottom w:type="dxa" w:w="0"/>
    								<w:right w:type="dxa" w:w="108"/>
    							</w:tblCellMar>
    						</w:tblPr>
    						<w:tblGrid>
    							<w:gridCol w:w="1185"/>
    							<w:gridCol w:w="1664"/>
    							<w:gridCol w:w="1336"/>
    							<w:gridCol w:w="1364"/>
    							<w:gridCol w:w="1816"/>
    							<w:gridCol w:w="1380"/>
    						</w:tblGrid>
    						<w:tr>
    							<w:tblPrEx>
    								<w:tblBorders>
    									<w:top w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    									<w:left w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    									<w:bottom w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    									<w:right w:color="auto" w:space="0" w:sz="12" w:val="single"/>
    									<w:insideH w:color="auto" w:space="0" w:sz="4" w:val="single"/>
    									<w:insideV w:color="auto" w:space="0" w:sz="4" w:val="single"/>
    								</w:tblBorders>
    							</w:tblPrEx>
    							<w:trPr>
    								<w:trHeight w:hRule="atLeast" w:val="630"/>
    								<w:jc w:val="center"/>
    							</w:trPr>
    							<w:tc>
    								<w:tcPr>
    									<w:tcW w:type="dxa" w:w="1185"/>
    									<w:vMerge w:val="restart"/>
    									<w:shd w:color="auto" w:fill="C0C0C0" w:val="clear"/>
    									<w:vAlign w:val="center"/>
    								</w:tcPr>
    								<w:p>
    									<w:r>
    										<w:t>申请人</w:t>
    									</w:r>
    									<w:r>
    										<w:br w:type="textWrapping"/>
    									</w:r>
    									<w:bookmarkStart w:id="0" w:name="_GoBack"/>
    									<w:r>
    										<w:t>信用等级</w:t>
    									</w:r>
    									<w:bookmarkEnd w:id="0"/>
    								</w:p>
    							</w:tc>
    						</w:tr>
    					</w:tbl>
    

    大体对标签字段解释如下:

    <w:tbl>:表格开始
    <w:tblPr> :表格属性定义
    <w:tblGrid>:表格单元格定义,里面定义着从左至右每个最小单元格的宽度,如果某个单元格span为2,则会在cell中定义<w:gridSpan w:val=“2”/>
    <w:trPr>:表格每一行的属性定义
    <w:tc>:表格中某个单元格的属性定义
    <w:vMerge w:val=“restart”/>:表示这个单元格跨行,并且是跨行的第一个cell
    <w:vMerge w:val=“continue”/>:表示这个单元格跨行,但不是跨行的第一个cell
    <w:p>:word中的一个段落
    <w:r>:段落中的一个格式一致的文本块
    我们使用poi包中的方法对xml文件中的字段进行解析,抽取出文件中的结构,并根据位置信息填充必要的结构信息。

    1. 抽取文字元素
    // 读取docx文字部分
    StringBuilder docxText = new StringBuilder();
    Iterator<IBodyElement> iter = docx.getBodyElementsIterator();
    int count = 0;
    while (iter.hasNext()) {
        IBodyElement element = iter.next();
        if (element instanceof XWPFParagraph) {
            // 获取段落元素
            XWPFParagraph paragraph = (XWPFParagraph) element;
            String text = paragraph.getText();
            if (StringUtils.isBlank(text)) {
                continue;
            }
            // 将word中的特有字符转化为普通的换行符、空格符等
            String textWithSameBlankAndBreak = text.replaceAll(WORD_BLANK, " ").replaceAll(WORD_LINE_BREAK, "\n")
                    .replaceAll("\n+", "\n");
            // 去除word特有的不可见字符
            String textClearBeginBlank = textWithSameBlankAndBreak.replaceAll(regexClearBeginBlank, "");
            // 为抽取的每一个段落加上\n作为换行符标识
            docxText.append(textClearBeginBlank).append("\n");
        } else if (element instanceof XWPFTable) {
            try {
                // 获取表格中的原始文字 默认文字中不加入表格文字 取消注释可加入
                /*String text = originTableTextList.get(count);
                docxText.append(text);*/
                count++;
            } catch (Exception e) {
                log.error("docx抽表数据与对应的表格位置不一致");
            }
        }
    }
    
    1. 抽取表格元素
      docx抽取表格的长宽主要使用两种方法,优先采用表格边框法:
    • 表格边框法:根据[相关规范]中的<w:tblPrEx>
    • 单元格法:根据[相关规范]中的<w:tcPr>
    • span:表示跨单元格,有rowspan和colspan两种
    List<WordTable> allWordTableCellList = new ArrayList<>();
    Iterator<XWPFTable> it = docx.getTablesIterator();
    // 抽取表中的文字集合
    List<String> originTableTextList = new ArrayList<>();
    while (it.hasNext()) {
        try {
            XWPFTable table = it.next();
            WordTable wordTable = new WordTable();
            List<WordTableCell> wordTableCellList = new ArrayList<>();
            // 默认每个表格左上角的位置为(0,0)
            float x = 0.0f;
            float y = 0.0f;
            // TblGridExist是记录表格的边框 如果存在的话用它来计算单元格宽度很准 但是不一定存在 else 会使用单元格法
            boolean isTblGridExist = true;
            // 一种计算width的方式,表格边框法
            List<CTTblGridCol> tableGridColList = null;
            try {
                // 尝试读取表格网格信息
                tableGridColList = table.getCTTbl().getTblGrid().getGridColList();
            } catch (Exception e) {
                log.info("该docx表格无边框");
                isTblGridExist = false;
            }
            // 采用表格边框法
            if (isTblGridExist) {
                for (int i = 0; i < table.getNumberOfRows(); i++) {
                    int colNums = table.getRow(i).getTableCells().size();
                    int currentRowHeight = getDocxRowHeight(table, i) / DEFAULT_DIV;
                    for (int j = 0, minCellNums = 0; j < colNums; j++) {
                        XWPFTableCell cell = table.getRow(i).getCell(j);
                        int spanNumber = 1;
                        // 表示colspan
                        BigInteger girdSpanBigInteger;
                        try {
                            girdSpanBigInteger = cell.getCTTc().getTcPr().getGridSpan().getVal();
                        } catch (Exception e) {
                            girdSpanBigInteger = null;
                        }
                        if (girdSpanBigInteger != null) {
                            spanNumber = girdSpanBigInteger.intValue();
                        }
                        int widthByGrid = 0;
                        for (int k = 0; k < spanNumber; k++) {
                            widthByGrid += tableGridColList.get(minCellNums + k).getW().intValue();
                        }
                        int width = widthByGrid / DEFAULT_DIV;
                        minCellNums += spanNumber;
    
                        if (!docxIsContinue(cell)) {
                            int height = this.getDocxCellHeight(table, currentRowHeight, i, j);
                            WordTableCell wordTableCell = this
                                    .buildWordCellContent((float) height, (float) width, cell.getText(),
                                            DEFAULT_FONT_SIZE, x, y);
                            wordTableCellList.add(wordTableCell);
                        }
                        x += width;
                    }
                    if (i + 1 == table.getNumberOfRows()) {
                        wordTable.setHeight(y);
                        wordTable.setWidth(x);
                    }
                    x = 0.0f;
                    y += currentRowHeight;
                }
            } else {
                // 另一种查看width方式,单元格法
                for (int i = 0; i < table.getNumberOfRows(); i++) {
                    int colNums = table.getRow(i).getTableCells().size();
                    int currentRowHeight = getDocxRowHeight(table, i) / DEFAULT_DIV;
                    for (int j = 0; j < colNums; j++) {
                        XWPFTableCell cell = table.getRow(i).getCell(j);
                        int width = getDocxCellWidth(table, i, j) / DEFAULT_DIV;
                        if (width <= 0) {
                            // tableGridMethod = true;
                            width = DEFAULT_WIDTH;
                        }
                        if (!docxIsContinue(cell)) {
                            int height = this.getDocxCellHeight(table, currentRowHeight, i, j);
                            WordTableCell wordTableCell = this
                                    .buildWordCellContent((float) height, (float) width, cell.getText(),
                                            DEFAULT_FONT_SIZE, x, y);
                            wordTableCellList.add(wordTableCell);
                        }
                        x += width;
                    }
                    if (i + 1 == table.getNumberOfRows()) {
                        wordTable.setHeight(y);
                        wordTable.setWidth(x);
                    }
                    x = 0.0f;
                    y += currentRowHeight;
                }
            }
    
            wordTable.setWordTableCellList(wordTableCellList);
            allWordTableCellList.add(wordTable);
            // 以下代码为为抽取的文字中加入表格文字
            /* 
            String originTableText = "<tb>\n" + table.getText().replaceAll(WORD_TABLE_FILTER, "") + "</tb>\n";
            originTableTextList.add(originTableText);
            */
        } catch (Exception e) {
            log.error("docx表格解析错误", e);
        }
    }
    // 为表格加入行列信息
    allWordTableCellList.forEach(this::fillSpan);
    // 开始抽取doc中的文字
    StringBuilder docText = new StringBuilder();
    for (int i = 0; i < range.numParagraphs(); i++) {
        Paragraph paragraph = range.getParagraph(i);
        // 拿出段落中不包括表格的文字
        if (!paragraph.isInTable()) {
            String text = paragraph.text();
            if (StringUtils.isBlank(text)) {
                continue;
            }
            String textWithSameBlankAndBreak = text.replaceAll(WORD_BLANK, " ").replaceAll(WORD_LINE_BREAK, "\n");
            String clearBeginBlank = textWithSameBlankAndBreak.replaceAll(regexClearBeginBlank, "");
            docText.append(clearBeginBlank).append("\n");
        } else {
            try {
                // 寻找表格的开始位置和结束位置
                int index = i;
                int endIndex = index;
                // 拿出表格中文字
                StringBuilder tableOriginText = new StringBuilder(paragraph.text());
                for (; index < range.numParagraphs(); index++) {
                    Paragraph tableParagraph = range.getParagraph(index);
                    if (!tableParagraph.isInTable() || tableParagraph.getTableLevel() < 1) {
                        endIndex = index;
                        break;
                    } else {
                        tableOriginText.append(tableParagraph.text());
                    }
                }
                i = endIndex - 1;
                // 过滤掉表格中所有不可见符号
                String tableOriginTextWithoutBlank = tableOriginText.toString().replaceAll(WORD_TABLE_FILTER, "");
                // 默认不加入表格中字体
                // docText.append("<tb>").append(tableOriginTextWithoutBlank).append("</tb>").append("\n");
            } catch (Exception e) {
                log.error("doc抽表数据与对应的表格位置不一致");
            }
    
    private int getDocCellToLeftWidth(Table table, int row, int col) {
        int leftWidth = 0;
        for (int i = 0; i < col; i++) {
            leftWidth += getDocCellWidth(table, row, i);
        }
        return leftWidth;
    }
    
    private int getDocCellWidth(Table table, int row, int col) {
        int width = table.getRow(row).getCell(col).getWidth() / DEFAULT_DIV;
        if (width < 0) {
            width = Math.abs(width);
            log.info("doc取出的宽度为负数");
        }
        return width == 0 ? DEFAULT_WIDTH : width;
    }
    
    private int getDocRowHeight(Table table, int row) {
        int height = table.getRow(row).getRowHeight();
        if (height < 0) {
            log.info("出现height小于0");
            height = Math.abs(height);
        }
        return height == 0 ? DEFAULT_HEIGHT : height;
    }
    
    /**
     * 只会传isRestart进来 判断往下是不是continue
     */
    private int getDocContinueRowHeight(Table table, int row, int col, int rowHeight) {
        int nextRow = row + 1;
        if (nextRow >= table.numRows()) {
            return rowHeight;
        }
        int nextRowHeight = getDocRowHeight(table, nextRow) / DEFAULT_DIV;
        int nextColNums = table.getRow(nextRow).numCells();
        for (int j = 0; j < nextColNums; j++) {
            TableCell nextRowCell = table.getRow(nextRow).getCell(j);
            if (docIsContinue(nextRowCell) && getDocCellWidth(table, nextRow, j) == getDocCellWidth(table, row, col)
                    && getDocCellToLeftWidth(table, nextRow, j) == getDocCellToLeftWidth(table, row, col)) {
                rowHeight += nextRowHeight;
                return getDocContinueRowHeight(table, nextRow, j, rowHeight);
            }
        }
        return rowHeight;
    }
    
    /**
     * 是否行合并单元格,但不是第一个
     */
    private boolean docIsContinue(TableCell cell) {
        return cell.isVerticallyMerged() && !cell.isFirstVerticallyMerged();
    }
    
    /**
     * 行合并单元格且为第一个
     */
    private boolean docIsRestart(TableCell cell) {
        return cell.isFirstVerticallyMerged();
    }
    

    先写到这里,后面看有没有人有word抽取结构化的需求再决定是否继续写下去。
    相关代码已上传至github,有帮助的话希望点个star,谢谢了。有问题欢迎留言或者私信我,有空我会解答。
    https://github.com/boyonger/word-extractor

    展开全文
  • 提取docx图片,文字表格元素

    千次阅读 2017-10-31 09:12:58
    话不多说,先介绍下思路,我是将word中文字,表格,图片按照顺序提取出来,然后返回为一个XML的Document元素,基本上重新定义了wordxml格式,原因是xml格式虽然采用xml元素,但是太过于复杂,对于此项目后续拓展...
  • 在EXCEL表格里,怎么提取某一单元格的一部分文字首先在电脑桌面上打开EXCEL表格,Excel的A列有如下数据,从中提取市名,例如A列提劝...在Excel可以用left函数某单元格 左侧开始提取部分文字,用right...
  • pdf 中提取表格信息、合并、解析、输出pdf 格式浅述 pdf 抽取表格所在的页 pdf 抽取表格合并表格、解析表格、生成输出数据 pdf 格式浅述 pdf 作为一种使用极为广泛的可移植文件格式,常用于各种用户...
  • 利用pdfplumber提取文字 import pdfplumber with pdfplumber.open("Netease Q2 2019 Earnings Release-Final.pdf") as pdf: first_page = pdf.pages[0] print(first_page.extract_text()) 利用pdfplumber提取...
  • 需要分割第一个表格中的机型,提取客户公司信息到第二个表格 实现效果 from openpyxl import load_workbook #1,读取工作表 wb = load_workbook("data\机型名称.xlsx") ws = wb.active #2,读取并拆分需要的...
  • 批处理——提取SRT文字中的文字

    千次阅读 2018-12-09 18:02:44
    需求:有同学备考需要,需要看中国慕课里面的视频,除了听还需要做笔记,有特殊情况的还需要背稿子,这里,介绍了一种将字幕文件的文字提取出来。 网址:http://www.feemic.cn/mooc  第一步,下载所需要课程的...
  • OpenCV-检测并提取表格

    万次阅读 多人点赞 2016-07-27 16:30:19
    检测并提取表格的方法:运用腐蚀膨胀提取横纵表格线,判断表格位置,并显示。
  • PDF 表格中获取数据是一项痛苦的工作。不久前,一位开发者提供了一个名为 Camelot 的工具,使用三...不久前,有一位开发者提供了一个可从文字 PDF 中提取表格信息的工具——Camelot,能够直接将大部分表格转换为 Pa
  • 0.安装模块 window: pip insta pypdf2 pip install pdfplumber mac: pip3 insta pypdf2 pip3 install pdfplumber 若错误可 pip install -i ... 1.提取pdf文字...
  • 要点初见:Python+OpenCV校正并提取表格中的各个框

    千次阅读 多人点赞 2018-12-12 17:55:53
    最近做了个手写汉字简历识别比赛,需要先提取表格中含有指定信息的各个框,再用TensorFlow对框的信息进行汉字、数字、英文识别。代码已开源:https://github.com/BingLiHanShuang/chinese_ocr,需要额外下载训练好...
  • 利用pdfplumber提取文字 pdfplumber.open(pdf路径)/pdf.pages[页数]/page.extract_text() import os os.chdir('D:\\python_major\\auto_office10') import pdfplumber with pdfplumber.open("Netease Q2 2019...
  • 其中, 处理Excel表格中, 最常用的就是按条件提取表格中的某些特征的内容; 对于的, 就要用到python的索引功能; 以下是要实操的案例数据的一部分 CardCount Type TermNo OperNo Dept 818 消费 ...
  • 向AI转型的程序员都关注了这个号????????????机器学习AI算法工程 公众号:datayx最近做了个手写汉字简历识别比赛,需要先提取表格中含有指定信息的各个框,再用Tenso...
  • 这是我个人运用Excel VBA在EXcel实现的提取单元格特定文字,并用”.“来标注此单元格是否存在这个字符的小程序。
  • 小伙伴们可能会觉得图像中提取文本是一件很麻烦的事情,尤其是需要提取大量文本时。PyTesseract是一种光学字符识别(OCR),该库提了供文本图像。 PyTesseract确实有一定的效果,用PyTesseract来检测短文本时,...
  • Excel表格中提取数字 1. 手动输入提取的第一行的数字 2.选中后面的要填充的数字的位置 3.按CTRL+E
  • Sub test() For Each cell In Range(“A1:A319”) On Error Resume Next cell.Offset(0, 1).Value = cell.Hyperlinks(1).Address Next End Sub 加上On Error Resume Next, 错误原因是:并不是所有的单元格中都有...
  • 在参加比赛过程,需要获取江苏省科学技术奖近十年的数据,因此需要在官网上获取相应的数据,再查找数据的过程发现,官网给出的数据,并不是完整的可以直接拿来用的 比如: ① 2018-2019年的人员及项目名单是...
  • 不能用wps文件 引用文档有中文,开头
  • 如何提取出ppt文字

    万次阅读 2013-09-16 12:15:30
    最近在看一位老师的教学视频,视频里大部分的知识都记录在ppt里,于是很想将ppt文字提取出来,如果我一页一页地粘贴复制的话,效率低到吓人,因为一章的ppt有130多页,于是在网上搜索了一下方法,与大家分享一下...
  • 项目作者:vinayak mehta参与:一鸣 PDF 表格中获取数据是一项痛苦的工作。不久前,一位开发者提供了一个名为 Camelot 的工具,使用三行代码就能 PDF 文件中提取...
  • PDF 文件是一种非常常用的文件格式,通常用于正式的电子版文件。它能够很好的将不同的排版格式固定下来,形成版面清晰且美观的展示效果。...不久前,有一位开发者提供了一个可从文字 PDF 中提取表格信息的工具——...
  • // 请求表格数据 getTableData ( ) { //通过$axios发送http get请求 this . $axios . get ( "/api/project/get/projectType?=Morning" ) . then ( res = > { res . data . map ( val = > { val ...
  • 导语2021年1月, 微信发布了微信8.0, 这次更新支持图片文字提取的功能。用户在聊天界面和朋友圈中长按图片就可以提取图片中文字,然后一键转发、复制或收藏。图片文字提取功能基于微信自研O...
  • 不久前,一位开发者提供了一个名为 Camelot 的工具,使用三行代码就能 PDF 文件中提取表格数据。 PDF 文件是一种非常常用的文件格式,通常用于正式的电子版文件。它能够很好的将不同的排版格式固定下来,形成版面...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,673
精华内容 5,469
关键字:

从表格中提取部分文字