杰瑞科技汇

Java如何实现Excel转XML?

Of course! Converting Excel data to XML using Java is a common task for data integration, configuration, and web services. The most robust and popular way to achieve this is by using the Apache POI library to read the Excel file and the JDOM or DOM library to build the XML document.

Java如何实现Excel转XML?-图1
(图片来源网络,侵删)

Here’s a complete, step-by-step guide with code examples.

Recommended Libraries

  1. Apache POI: The de-facto standard for reading and writing Microsoft Office formats (like .xls and .xlsx) in Java.
  2. JDOM: A user-friendly, Java-specific library for creating and manipulating XML documents. It's often easier to use than the standard javax.xml DOM API.
  3. (Alternative) DOM API: If you don't want to add another dependency, you can use the built-in javax.xml.parsers.DocumentBuilder. The code is slightly more verbose.

Step 1: Set Up Your Project (Maven)

The easiest way to manage dependencies is with Maven or Gradle. If you're using Maven, add the following dependencies to your pom.xml file.

<dependencies>
    <!-- Apache POI for reading Excel files -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version>
    </dependency>
    <!-- JDOM for creating XML -->
    <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom2</artifactId>
        <version>2.0.6.1</version>
    </dependency>
</dependencies>

Step 2: Prepare Your Excel File

Let's assume you have an Excel file named data.xlsx with the following structure. The first row is the header, and subsequent rows are the data.

data.xlsx

Java如何实现Excel转XML?-图2
(图片来源网络,侵删)
Name City Age
Alice New York 30
Bob London 25
Charlie Tokyo 35

Step 3: Write the Java Code

We will create a Java class that reads the data.xlsx file and converts it into an XML structure like this:

<people>
    <person>
        <Name>Alice</Name>
        <City>New York</City>
        <Age>30</Age>
    </person>
    <person>
        <Name>Bob</Name>
        <City>London</City>
        <Age>25</Age>
    </person>
    <person>
        <Name>Charlie</Name>
        <City>Tokyo</City>
        <Age>35</Age>
    </person>
</people>

Here is the complete Java code to perform the conversion.

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jdom2.*;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ExcelToXmlConverter {
    public static void main(String[] args) {
        // Define file paths
        String excelFilePath = "data.xlsx";
        String xmlFilePath = "output.xml";
        try {
            // 1. Read data from Excel
            List<List<String>> excelData = readExcel(excelFilePath);
            // 2. Convert data to XML
            Element rootElement = convertToXml(excelData);
            // 3. Write XML to a file
            writeXmlToFile(rootElement, xmlFilePath);
            System.out.println("Successfully converted Excel to XML: " + xmlFilePath);
        } catch (IOException e) {
            System.err.println("Error reading the Excel file: " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("An unexpected error occurred: " + e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * Reads data from an Excel file and returns it as a list of lists of strings.
     * @param filePath The path to the Excel file.
     * @return A list where each inner list represents a row.
     * @throws IOException If an I/O error occurs.
     */
    private static List<List<String>> readExcel(String filePath) throws IOException {
        List<List<String>> data = new ArrayList<>();
        FileInputStream fis = new FileInputStream(new File(filePath));
        Workbook workbook = new XSSFWorkbook(fis); // Use XSSFWorkbook for .xlsx, HSSFWorkbook for .xls
        Sheet sheet = workbook.getSheetAt(0); // Get the first sheet
        // Iterate through rows (skip header row if needed)
        for (Row row : sheet) {
            List<String> rowData = new ArrayList<>();
            // Iterate through cells
            for (Cell cell : row) {
                // Handle different cell types
                switch (cell.getCellType()) {
                    case STRING:
                        rowData.add(cell.getStringCellValue());
                        break;
                    case NUMERIC:
                        // Check if it's an integer or a double
                        if (DateUtil.isCellDateFormatted(cell)) {
                            rowData.add(cell.getDateCellValue().toString());
                        } else {
                            rowData.add(String.valueOf((int) cell.getNumericCellValue())); // Treat as integer
                        }
                        break;
                    case BOOLEAN:
                        rowData.add(String.valueOf(cell.getBooleanCellValue()));
                        break;
                    case FORMULA:
                        rowData.add(cell.getCellFormula());
                        break;
                    default:
                        rowData.add("");
                }
            }
            // Add row data to the main list, skipping empty rows if desired
            if (!rowData.isEmpty()) {
                data.add(rowData);
            }
        }
        workbook.close();
        fis.close();
        return data;
    }
    /**
     * Converts the 2D list data into a JDOM Element tree.
     * @param excelData The data read from the Excel file.
     * @return The root Element of the XML tree.
     */
    private static Element convertToXml(List<List<String>> excelData) {
        // The first row is assumed to be the header
        List<String> headers = excelData.get(0);
        // The rest are the data rows
        List<List<String>> dataRows = excelData.subList(1, excelData.size());
        // Create the root element
        Element rootElement = new Element("people");
        // Iterate over each data row
        for (List<String> row : dataRows) {
            Element personElement = new Element("person");
            // Iterate over each cell in the row and pair it with the header
            for (int i = 0; i < headers.size(); i++) {
                // Use the header as the XML tag name
                String header = headers.get(i);
                // Get the cell value, defaulting to an empty string if out of bounds
                String value = (i < row.size()) ? row.get(i) : "";
                Element fieldElement = new Element(header);
                fieldElement.setText(value);
                personElement.addContent(fieldElement);
            }
            rootElement.addContent(personElement);
        }
        return rootElement;
    }
    /**
     * Writes the JDOM Element tree to an XML file.
     * @param rootElement The root element of the XML document.
     * @param filePath The path to the output XML file.
     * @throws IOException If an I/O error occurs.
     */
    private static void writeXmlToFile(Element rootElement, String filePath) throws IOException {
        // Create a new JDOM Document
        Document document = new Document(rootElement);
        // Format the XML for pretty printing
        XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
        // Write the document to a file
        xmlOutputter.output(document, new FileOutputStream(filePath));
    }
}

How to Run the Code

  1. Save the code as ExcelToXmlConverter.java.

  2. Place your data.xlsx file in the same directory.

    Java如何实现Excel转XML?-图3
    (图片来源网络,侵删)
  3. Compile and run the Java file. You can do this from your IDE or using the command line:

    # Compile (ensure poi and jdom2 jars are in the classpath)
    javac -cp ".:poi-5.2.5.jar:poi-ooxml-5.2.5.jar:poi-ooxml-lite-5.2.5.jar:xmlbeans-5.1.1.jar:stax-api-1.0.1.jar:stax-api-1.0.2.jar:jdom2-2.0.6.1.jar" ExcelToXmlConverter.java
    # Run
    java -cp ".:poi-5.2.5.jar:poi-ooxml-5.2.5.jar:poi-ooxml-lite-5.2.5.jar:xmlbeans-5.1.1.jar:stax-api-1.0.1.jar:stax-api-1.0.2.jar:jdom2-2.0.6.1.jar" ExcelToXmlConverter

    (Note: On Windows, the classpath separator is instead of )

After running, a new file named output.xml will be created in the same directory with the XML content.


Alternative: Using the Standard DOM API

If you prefer not to use JDOM, you can use Java's built-in javax.xml libraries. The logic is very similar, but the API is more verbose.

Here's how you would modify the convertToXml and writeXmlToFile methods:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
// ... (keep readExcel method from the previous example)
private static org.w3c.dom.Element convertToXmlWithDOM(List<List<String>> excelData) throws ParserConfigurationException {
    List<String> headers = excelData.get(0);
    List<List<String>> dataRows = excelData.subList(1, excelData.size());
    // Create a DocumentBuilderFactory and DocumentBuilder
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    // Create a new Document
    Document doc = docBuilder.newDocument();
    // Create the root element
    Element rootElement = doc.createElement("people");
    doc.appendChild(rootElement);
    for (List<String> row : dataRows) {
        Element personElement = doc.createElement("person");
        for (int i = 0; i < headers.size(); i++) {
            String header = headers.get(i);
            String value = (i < row.size()) ? row.get(i) : "";
            Element fieldElement = doc.createElement(header);
            fieldElement.appendChild(doc.createTextNode(value));
            personElement.appendChild(fieldElement);
        }
        rootElement.appendChild(personElement);
    }
    return rootElement;
}
private static void writeXmlToFileWithDOM(org.w3c.dom.Element rootElement, String filePath) throws TransformerException, IOException {
    // The rootElement is already part of a Document, so we get its owner document
    Document doc = rootElement.getOwnerDocument();
    // Create a TransformerFactory
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    // Set output properties (pretty print)
    transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    // Define the source and result
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(new FileOutputStream(filePath));
    // Transform the document to the output file
    transformer.transform(source, result);
}
// In your main method, you would call these new methods:
// org.w3c.dom.Element domRoot = convertToXmlWithDOM(excelData);
// writeXmlToFileWithDOM(domRoot, xmlFilePath);

Summary and Best Practices

  • Choose Your XML Library: JDOM is generally recommended for its simplicity and readability. The standard DOM API is a good alternative if you want to minimize external dependencies.
  • Error Handling: The provided code includes basic try-catch blocks. In a production environment, you might want more specific error handling (e.g., for file not found, invalid Excel format).
  • File Format: The code uses XSSFWorkbook for modern .xlsx files. For legacy .xls files, you would use HSSFWorkbook.
  • Data Types: The readExcel method handles common cell types (String, Numeric, Boolean). You may need to extend this for more complex scenarios like dates or formulas.
  • Large Files: For very large Excel files, consider using SXSSFWorkbook (from POI) for streaming to avoid memory issues. The JDOM/DOM approach builds the entire XML tree in memory, which can be a problem for huge datasets.
分享:
扫描分享到社交APP
上一篇
下一篇