杰瑞科技汇

java document 解析

目录

  1. XML 文档解析

    java document 解析-图1
    (图片来源网络,侵删)
    • SAX (Simple API for XML)
    • DOM (Document Object Model)
    • StAX (Streaming API for XML)
    • JAXB (Java Architecture for XML Binding)
    • 总结与选择建议
  2. JSON 文档解析

    • Jackson
    • Gson
    • org.json
    • 总结与选择建议
  3. HTML 文档解析

    • Jsoup
    • 总结与选择建议
  4. CSV 文档解析

    • OpenCSV
    • Apache Commons CSV
    • Java 8+ Stream (简单场景)
    • 总结与选择建议
  5. 通用文档解析 (基于 POI)

    java document 解析-图2
    (图片来源网络,侵删)

XML 文档解析

XML 是一种标记语言,在 Java 中有非常成熟的解析方案。

a. SAX (Simple API for XML)

  • 核心思想:事件驱动的流式解析器,它不会将整个 XML 文档加载到内存中,而是从上到下逐行读取,当解析器遇到开始标签、结束标签或文本内容时,会触发相应的事件(如 startElement, endElement, characters),开发者需要通过实现 ContentHandler 接口来处理这些事件。
  • 优点
    • 内存效率极高:因为它不构建整个文档树,只处理当前节点,所以非常适合解析非常大的 XML 文件。
    • 速度快:解析过程是顺序的,没有复杂的对象构建。
  • 缺点
    • 编程复杂:需要手动维护状态,如果需要访问文档的任意部分,会非常困难。
    • 只读:只能读取数据,不能修改或创建 XML 文档。
  • 适用场景:处理大型 XML 文件,且只需要顺序读取数据,例如日志文件、配置文件等。
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;
public class SaxParserExample {
    public static void main(String[] args) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            // 假设有一个 books.xml 文件在 classpath 下
            InputStream inputStream = SaxParserExample.class.getResourceAsStream("/books.xml");
            DefaultHandler handler = new DefaultHandler() {
                boolean inBook = false;
                boolean inTitle = false;
                boolean inAuthor = false;
                @Override
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                    if (qName.equalsIgnoreCase("book")) {
                        inBook = true;
                        System.out.println("\n--- 开始解析一本书 ---");
                        String id = attributes.getValue("id");
                        System.out.println("Book ID: " + id);
                    } else if (inBook && qName.equalsIgnoreCase("title")) {
                        inTitle = true;
                    } else if (inBook && qName.equalsIgnoreCase("author")) {
                        inAuthor = true;
                    }
                }
                @Override
                public void characters(char[] ch, int start, int length) throws SAXException {
                    if (inTitle) {
                        System.out.println("Title: " + new String(ch, start, length));
                        inTitle = false;
                    }
                    if (inAuthor) {
                        System.out.println("Author: " + new String(ch, start, length));
                        inAuthor = false;
                    }
                }
                @Override
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    if (qName.equalsIgnoreCase("book")) {
                        inBook = false;
                    }
                }
            };
            saxParser.parse(inputStream, handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

b. DOM (Document Object Model)

  • 核心思想:将整个 XML 文档加载到内存中,构建一个树形结构(DOM 树),开发者可以通过操作这个树来访问、修改、添加或删除文档中的任何元素。
  • 优点
    • 编程简单直观:可以像操作普通对象一样操作 XML,可以随意导航、查询和修改文档。
    • 功能强大:支持 XPath 等查询语言,方便定位节点。
  • 缺点
    • 内存消耗大:整个文档都加载到内存中,对于大型文件会导致性能问题和内存溢出。
    • 速度较慢:加载和构建树需要时间。
  • 适用场景:XML 文档较小,或者需要对文档进行复杂的随机访问和修改操作。
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
public class DomParserExample {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputStream inputStream = DomParserExample.class.getResourceAsStream("/books.xml");
            Document document = builder.parse(inputStream);
            document.getDocumentElement().normalize();
            System.out.println("Root element: " + document.getDocumentElement().getNodeName());
            NodeList nodeList = document.getElementsByTagName("book");
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    System.out.println("\n--- Book " + (i + 1) + " ---");
                    System.out.println("ID: " + element.getAttribute("id"));
                    System.out.println("Title: " + element.getElementsByTagName("title").item(0).getTextContent());
                    System.out.println("Author: " + element.getElementsByTagName("author").item(0).getTextContent());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

c. StAX (Streaming API for XML)

  • 核心思想:介于 SAX 和 DOM 之间,它也是一种流式 API,但它允许应用程序“拉取”事件,而不是像 SAX 那样由解析器“推送”事件,开发者可以控制解析流程,随时暂停和继续。
  • 优点
    • 内存效率高:和 SAX 一样,不加载整个文档。
    • 编程比 SAX 简单:应用程序有更多的控制权,状态管理更容易。
    • 可读可写:既可以读取,也可以生成 XML。
  • 缺点

    不如 DOM 灵活,随机访问能力有限。

  • 适用场景:需要比 SAX 更多控制流的大型 XML 文件处理,或者需要同时读取和生成 XML。
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;
import java.io.InputStream;
public class StaxParserExample {
    public static void main(String[] args) {
        try {
            XMLInputFactory factory = XMLInputFactory.newInstance();
            InputStream inputStream = StaxParserExample.class.getResourceAsStream("/books.xml");
            XMLEventReader eventReader = factory.createXMLEventReader(inputStream);
            while (eventReader.hasNext()) {
                XMLEvent event = eventReader.nextEvent();
                if (event.isStartElement()) {
                    String elementName = event.asStartElement().getName().getLocalPart();
                    if (elementName.equals("book")) {
                        System.out.println("\n--- 开始解析一本书 ---");
                        String id = event.asStartElement().getAttributeByName("id").getValue();
                        System.out.println("Book ID: " + id);
                    }
                } else if (event.isEndElement()) {
                    String elementName = event.asEndElement().getName().getLocalPart();
                    if (elementName.equals("book")) {
                        System.out.println("--- 结束解析一本书 ---");
                    }
                } else if (event.isCharacters()) {
                    String data = event.asCharacters().getData().trim();
                    if (!data.isEmpty()) {
                        // 简单判断父元素
                        // 实际项目中需要更复杂的状态管理
                        System.out.println("Content: " + data);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

d. JAXB (Java Architecture for XML Binding)

  • 核心思想:这是一种数据绑定技术,它能够将 Java 对象与 XML 文档自动进行映射,通过注解(如 @XmlRootElement, @XmlElement),你可以告诉 JAXB 如何将一个 Java 类序列化为 XML,或者将 XML 反序列化为 Java 对象。
  • 优点
    • 开发效率极高:代码非常简洁,只需定义 POJO (Plain Old Java Object),无需编写解析逻辑。
    • 面向对象:操作的是 Java 对象,而不是底层的 XML 节点,更符合 Java 编程思想。
  • 缺点
    • 依赖 Java 9+ 的模块系统:在 Java 9 及更高版本中,JAXB 不再包含在 JDK 中,需要单独添加 jakarta.xml.bind-api 和实现(如 com.sun.xml.bind:jaxb-impl)依赖。
    • 内存消耗大:本质上还是基于 DOM,需要将整个 XML 映射到对象树。
  • 适用场景:在 Web 服务(如 JAX-WS, JAX-RS)中处理 XML 数据,或者任何需要将 XML 与 Java 对象进行频繁转换的场景。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.InputStream;
import java.util.List;
// 1. 定义与 XML 结构对应的 Java 类
@XmlRootElement(name = "catalog")
class Catalog {
    @XmlElement(name = "book")
    private List<Book> books;
    // getters and setters
}
class Book {
    @XmlAttribute
    private String id;
    @XmlElement
    private String title;
    @XmlElement
    private String author;
    // getters and setters
}
// 2. 使用 JAXB 进行解析
public class JaxbParserExample {
    public static void main(String[] args) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Catalog.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            InputStream inputStream = JaxbParserExample.class.getResourceAsStream("/books.xml");
            Catalog catalog = (Catalog) unmarshaller.unmarshal(inputStream);
            for (Book book : catalog.getBooks()) {
                System.out.println("ID: " + book.getId() + ", Title: " + book.getTitle() + ", Author: " + book.getAuthor());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

XML 解析总结与选择建议

特性 SAX DOM StAX JAXB
内存占用 极低
速度 较快 较快
易用性 复杂 简单 中等 非常简单
功能 只读 读写 读写 读写(对象映射)
适用场景 大文件、顺序读取 小文件、随机访问、修改 大文件、需要控制流 Web服务、对象与XML转换
  • 选择 SAX:当处理几百兆甚至更大的 XML 文件,且你只需要从头到尾扫描一遍数据时。
  • 选择 DOM:当 XML 文件很小(几兆以内),或者你需要频繁地在文档中跳转、查询、修改数据时。
  • 选择 StAX:当你需要比 SAX 更好的控制流,或者同时需要读写 XML,但又不想承受 DOM 的内存开销时。
  • 选择 JAXB:当你主要关心的是将 XML 数据转换成 Java 对象进行业务处理,而不想关心底层 XML 解析细节时,这是现代 Java 开发中最常用、最高效的方式之一。

JSON 文档解析

JSON 是目前最流行的数据交换格式,Java 生态中有三大主流库。

a. Jackson

  • 核心思想:功能强大、性能极高、社区活跃的 JSON 处理库,它不仅能进行对象绑定,还支持树模型、流式 API 等多种处理方式。
  • 优点
    • 性能卓越:在所有 JSON 库中通常是最快的。
    • 功能全面:支持数据绑定、树模型、流式 API、注解、模块化扩展(如支持 Java 8 时间类型)。
    • 生态好:Spring Framework 默认使用 Jackson。
  • 缺点

    API 相对复杂,有陡峭的学习曲线。

  • 适用场景:几乎所有场景,尤其是对性能有要求的 Web 应用、微服务、大数据处理。
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.InputStream;
// 1. 定义一个与 JSON 结构匹配的 Java 类
class User {
    private String name;
    private int age;
    // getters and setters
}
public class JacksonExample {
    public static void main(String[] args) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            // 从文件解析
            // User user = mapper.readValue(new File("user.json"), User.class);
            // 从字符串解析
            String jsonString = "{\"name\":\"Alice\",\"age\":30}";
            User user = mapper.readValue(jsonString, User.class);
            System.out.println("Name: " + user.getName());
            System.out.println("Age: " + user.getAge());
            // 将对象转换为 JSON 字符串
            String jsonOutput = mapper.writeValueAsString(user);
            System.out.println("\nOutput JSON: " + jsonOutput);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

b. Gson

  • 核心思想:由 Google 开发,以其简洁的 API 和易用性而闻名。
  • 优点
    • API 简单直观:非常容易上手,代码可读性高。
    • 轻量级:库体积小。
    • 功能稳定:经过 Google 内部大规模项目的长期检验。
  • 缺点

    性能略逊于 Jackson。

  • 适用场景:中小型项目,或者对开发便利性要求高于极致性能的场景。
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;
public class GsonExample {
    public static void main(String[] args) {
        Gson gson = new Gson();
        String jsonString = "{\"name\":\"Bob\",\"age\":25}";
        // 解析为对象
        User user = gson.fromJson(jsonString, User.class);
        System.out.println("Name: " + user.getName());
        System.out.println("Age: " + user.getAge());
        // 解析为 Map
        Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
        Map<String, Object> dataMap = gson.fromJson(jsonString, mapType);
        System.out.println("\nData as Map: " + dataMap);
        // 对象转 JSON
        String jsonOutput = gson.toJson(user);
        System.out.println("\nOutput JSON: " + jsonOutput);
    }
}

c. org.json

  • 核心思想:一个非常轻量级的库,提供了 JSONObjectJSONArray 两个核心类来直接操作 JSON 数据。
  • 优点
    • 非常轻量:只有一个 JAR 文件。
    • API 直接:直接操作 JSON 结构,无需创建 Java 类。
  • 缺点
    • 需要手动处理类型转换,容易出错。
    • 功能相对较少,没有数据绑定。
  • 适用场景:只需要快速解析或生成简单的 JSON,而不想定义对应的 Java 类。
import org.json.JSONObject;
import org.json.JSONArray;
public class OrgJsonExample {
    public static void main(String[] args) {
        String jsonString = "{\"name\":\"Charlie\",\"age\":40,\"hobbies\":[\"reading\",\"swimming\"]}";
        // 解析 JSONObject
        JSONObject jsonObject = new JSONObject(jsonString);
        String name = jsonObject.getString("name");
        int age = jsonObject.getInt("age");
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        // 解析 JSONArray
        JSONArray hobbies = jsonObject.getJSONArray("hobbies");
        for (int i = 0; i < hobbies.length(); i++) {
            System.out.println("Hobby " + (i + 1) + ": " + hobbies.getString(i));
        }
        // 构建 JSON
        JSONObject newJson = new JSONObject();
        newJson.put("city", "New York");
        System.out.println("\nNew JSON: " + newJson.toString());
    }
}

JSON 解析总结与选择建议

特性 Jackson Gson org.json
性能 中等 中等
易用性 中等 中等
功能 全面 良好 基础
生态 好 (Spring) 一般
适用场景 高性能、企业级应用 中小型、快速开发 轻量级、简单操作
  • 首选 Jackson:如果你在构建一个新的项目,特别是企业级应用或微服务,Jackson 是不二之选,它的性能和功能都无与伦比。
  • 选择 Gson:如果你来自 Google 生态,或者项目对 API 的简洁性要求很高,Gson 是一个非常好的选择。
  • 选择 org.json:当你只需要在一个小工具或一个方法中处理一下 JSON,不想引入复杂的对象映射关系时,它很方便。

HTML 文档解析

HTML 格式不严谨,用 XML 解析器(如 DOM)解析很容易失败,需要专门的 HTML 解析器。

Jsoup

  • 核心思想:一个专门为 Java 设计的、非常方便的 HTML 解析库,它提供了类似 jQuery 的 CSS 选择器 API,可以非常轻松地提取和操作数据。
  • 优点
    • API 极其友好:使用 CSS 选择器 (select, id, class) 提取数据,直观高效。
    • 容错性强:能很好地处理格式不规范的 HTML。
    • 功能丰富:不仅能解析,还能修改、清理 HTML,并支持从 URL 或文件直接加载。
  • 缺点

    仅适用于 HTML,不适用于 XML 或 JSON。

  • 适用场景:网页爬虫、数据抓取、从 HTML 字符串中提取信息。
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class JsoupExample {
    public static void main(String[] args) {
        String html = "<html><head><title>Jsoup Test</title></head>"
                + "<body>"
                + "<div class='header'>Welcome</div>"
                + "<p>This is a paragraph.</p>"
                + "<ul><li>Item 1</li><li>Item 2</li></ul>"
                + "</body></html>";
        // 从字符串解析
        Document doc = Jsoup.parse(html);
        // 1. 提取标题
        String title = doc.title();
        System.out.println("Title: " + title);
        // 2. 使用 CSS 选择器提取元素
        // 提取 class 为 'header' 的 div 的文本
        Element header = doc.select("div.header").first();
        System.out.println("Header text: " + header.text());
        // 提取所有 <li> 元素
        Elements listItems = doc.select("li");
        System.out.println("\nList items:");
        for (Element li : listItems) {
            System.out.println("- " + li.text());
        }
        // 3. 从 URL 抓取 (需要网络权限)
        try {
            // Document onlineDoc = Jsoup.connect("https://en.wikipedia.org/wiki/Main_Page").get();
            // String pageTitle = onlineDoc.title();
            // System.out.println("\nOnline Page Title: " + pageTitle);
        } catch (IOException e) {
            System.out.println("无法连接到 URL: " + e.getMessage());
        }
    }
}

CSV 文档解析

CSV 是一种简单的表格数据格式。

a. OpenCSV

  • 核心思想:一个功能强大且流行的 CSV 处理库。
  • 优点
    • 功能全面:支持自动类型转换、自定义分隔符、处理带引号的字段等复杂情况。
    • 易于使用:提供简单的 API 来读取和写入 CSV 文件。
  • 缺点

    需要引入第三方依赖。

  • 适用场景:任何需要处理 CSV 文件的场景,尤其是格式可能比较复杂的 CSV。
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvValidationException;
import java.io.FileReader;
import java.io.IOException;
public class OpenCsvExample {
    public static void main(String[] args) {
        String csvFile = "data.csv"; // 假设文件内容为: name,age\nAlice,30\nBob,25
        CSVReader reader = null;
        try {
            reader = new CSVReader(new FileReader(csvFile));
            String[] nextLine;
            // 读取表头
            if ((nextLine = reader.readNext()) != null) {
                System.out.println("Header: " + nextLine[0] + ", " + nextLine[1]);
            }
            // 读取数据行
            while ((nextLine = reader.readNext()) != null) {
                System.out.println("Name: " + nextLine[0] + ", Age: " + nextLine[1]);
            }
        } catch (IOException | CsvValidationException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

b. Apache Commons CSV

  • 核心思想:由 Apache 软件基金会维护,提供了更现代和灵活的 API。
  • 优点
    • API 设计优秀:使用 RecordHeader 等概念,代码更清晰。
    • 可扩展性强:支持自定义格式和解析策略。
  • 缺点

    API 比 OpenCSV 稍微复杂一点。

  • 适用场景:与 OpenCSV 类似,但如果你更喜欢 Apache 的设计哲学,这是一个绝佳选择。
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class ApacheCommonsCsvExample {
    public static void main(String[] args) {
        String csvFile = "data.csv";
        try (Reader reader = new FileReader(csvFile);
             CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT.withFirstRecordAsHeader())) {
            for (CSVRecord record : csvParser) {
                String name = record.get("name"); // 使用表头作为键
                String age = record.get("age");
                System.out.println("Name: " + name + ", Age: " + age);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

c. Java 8+ Stream (简单场景)

  • 核心思想:对于最简单的、没有引号、没有转义字符的 CSV 文件,可以直接使用 Java 8 的 Stream API 和 BufferedReader 来逐行处理。
  • 优点
    • 零依赖:不需要引入任何第三方库。
  • 缺点
    • 功能极其有限:无法处理包含逗号、换行符等复杂情况的 CSV 文件,容易出错。
  • 适用场景:处理由程序自己生成、格式绝对简单的 CSV 文件。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class JavaStreamCsvExample {
    public static void main(String[] args) {
        String csvFile = "simple_data.csv"; // 内容: name,age\nAlice,30\nBob,25
        String line;
        String csvSplitBy = ",";
        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
            // 读取并丢弃表头
            br.readLine();
            while ((line = br.readLine()) != null) {
                String[] person = line.split(csvSplitBy);
                System.out.println("Name: " + person[0] + ", Age: " + person[1]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

CSV 解析总结与选择建议

特性 OpenCSV Apache Commons CSV Java 8 Stream
易用性 简单 优秀 极简
功能 强大 强大 极其有限
依赖 需要 需要
适用场景 通用、复杂 CSV 通用、追求设计 超简单、无依赖
  • 首选 OpenCSV 或 Apache Commons CSV:对于任何生产环境,都应该使用它们,两者都非常出色,Apache Commons CSV 的 API 设计可能更现代一些。
  • 选择 Java Stream:仅在 100% 确认你的 CSV 文件格式极其简单,且无法引入外部依赖时使用。

通用文档解析 (基于 POI)

Apache POI (Poor Obfuscation Implementation) 是一个强大的 Java API,用于操作 Microsoft Office 格式文件,如 Word (.docx), Excel (.xlsx), PowerPoint (.pptx)。

  • 核心思想:POI 提供了不同的模型来解析这些基于 ZIP 格式的 OOXML 文档。
    • 用户模型:最直观的方式,将整个文档加载到内存中,形成一个对象树,类似于 DOM,易于使用,但内存消耗大。
    • SAX (事件) 模型:流式解析,内存效率高,类似于 XML 的 SAX,适用于处理大型 Excel 文件。
  • 适用场景:需要读取、创建或修改 Office 文档的应用程序,如报表生成、数据导入导出等。
// 这是一个 Excel (.xlsx) 解析的示例
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class PoiExample {
    public static void main(String[] args) {
        String excelFilePath = "data.xlsx";
        try (FileInputStream fis = new FileInputStream(excelFilePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
            for (Row row : sheet) {
                for (Cell cell : row) {
                    switch (cell.getCellType()) {
                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;
                        case NUMERIC:
                            System.out.print(cell.getNumericCellValue() + "\t");
                            break;
                        case BOOLEAN:
                            System.out.print(cell.getBooleanCellValue() + "\t");
                            break;
                        default:
                            System.out.print("\t");
                    }
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
文档类型 推荐库 核心特点
XML JAXB (对象绑定), StAX (流式) JAXB 简化开发,StAX 平衡性能与控制
JSON Jackson (性能之王), Gson (简洁易用) Jackson 适合企业级,Gson 适合中小型项目
HTML Jsoup CSS 选择器 API,极其方便,容错性强
CSV OpenCSVApache Commons CSV 功能强大,能处理复杂格式,比手写健壮
Office Apache POI 功能全面,支持 Word, Excel, PowerPoint 等

选择哪个库,最终取决于你的具体需求:文件大小、性能要求、开发效率、以及是否需要修改文档,对于大多数现代 Java 应用,Jackson (JSON)Jsoup (HTML) 是最常遇到的组合。

分享:
扫描分享到社交APP
上一篇
下一篇