jsoup解析html之table表格
jsoup说明
一款Java 的HTML解析器
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
主要功能
- 从一个URL,文件或字符串中解析HTML;
- 使用DOM或CSS选择器来查找、取出数据;
- 可操作HTML元素、属性、文本;
需求说明
现在需要从上游过来一批数据,我们解析之后做一些逻辑处理,批量录入数据库;这些数据就是excel,一条一条的,只不过它不是标准的xls
或者xlsx
形式,而是处理过的html
格式加工成xls
格式,如果我们使用easypoi
或者easyexcel
解析会出现错误提示java.io.IOException: Your InputStream was neither an OLE2 stream, nor an OOXML stream,简而言之就是,这两个解析框架不识别,不是标准的xls
或者xlsx
,解决方法就是从上游导出的数据,先保存为标准的xls
后者xlsx
形式不会出现问题,但是,但是,现在需要从程序上进行控制。
代码操作
核心api
Jsoup
The core public access point to the jsoup functionality.
Parse HTML into a Document. The parser will make a sensible, balanced document tree out of any HTML.
Document :文档对象。每份HTML页面都是一个文档对象,Document 是 jsoup 体系中最顶层的结构。
Element:元素对象。一个 Document 中可以着包含着多个 Element 对象,可以使用 Element 对象来遍历节点提取数据或者直接操作HTML。
Elements:元素对象集合,类似于List。
核心方法
eachText()
/**
* Get the text content of each of the matched elements. If an element has no text, then it is not included in the
* result.
* @return A list of each matched element's text content.
* @see Element#text()
* @see Element#hasText()
* @see #text()
*/
public List<String> eachText() {
ArrayList<String> texts = new ArrayList<>(size());
for (Element el: this) {
if (el.hasText())
texts.add(el.text());
}
return texts;
}
select()
/**
* Find matching elements within this element list.
* @param query A {@link Selector} query
* @return the filtered list of elements, or an empty list if none match.
*/
public Elements select(String query) {
return Selector.select(query, this);
}
1.select()方法在Document、Element或Elements对象中都可以使用,而且是上下文相关的,因此可实现指定元素的过滤,或者采用链式访问。
2.select() 方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。
// 从文件流中获取html解析
public static Document parse(InputStream in, String charsetName, String baseUri) throws IOException {
return DataUtil.load(in, charsetName, baseUri);
}
// 从文件中获取html解析
public static Document parse(File in, String charsetName) throws IOException {
return DataUtil.load(in, charsetName, in.getAbsolutePath());
}
public static Document parse(File in, String charsetName, String baseUri) throws IOException {
return DataUtil.load(in, charsetName, baseUri);
}
public static Document parse(InputStream in, String charsetName, String baseUri, Parser parser) throws IOException {
return DataUtil.load(in, charsetName, baseUri, parser);
}
package com.geekmice.springbootselfexercise.utils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.geekmice.springbootselfexercise.exception.UserDefinedException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
* @BelongsProject: spring-boot-self-exercise
* @BelongsPackage: com.geekmice.springbootselfexercise.utils
* @Author: pingmingbo
* @CreateTime: 2023-08-13 17:16
* @Description: 解析html
* @Version: 1.0
*/
@Slf4j
public class ParseHtmlUtil {
public static final String ERROR_MSG = "error mg:【{}】";
/**
* @param inputStream 文件流
* @return 解析好的数据list
* @throws IOException
* @description 根据文件流解析html格式的excel
* 问题说明:去除第一行标题,空行,空格,空指针问题
*/
public static List<String> parseHandle(InputStream inputStream) {
Document document;
try {
document = Jsoup.parse(inputStream, StandardCharsets.UTF_8.toString(), "");
} catch (IOException e) {
log.error(ERROR_MSG, e);
throw new UserDefinedException(e.toString());
}
Elements trList = document.select("table").select("tr");
List<String> abcList = trList.eachText();
if (CollectionUtils.isEmpty(abcList)) {
throw new UserDefinedException("解析文件:文件内容不存在");
}
abcList.remove(0);
return abcList;
}
}
效果展示
{
"msg": "操作成功",
"code": 200,
"data": [
"2023-07-28 00:15 上海 购方 0 0",
"2023-07-28 00:30 上海 购方 0 0",
....
"2023-07-28 23:00 四川主网 售方 333.25 225.94",
"2023-07-28 23:15 四川主网 售方 463.25 224.16",
"2023-07-28 23:30 四川主网 售方 463.25 224.16",
"2023-07-28 23:45 四川主网 售方 463.25 224.16",
"2023-07-28 24:00 四川主网 售方 587.79 213.53"
]
}