Of course! Converting JSON to Excel in Java is a common task. The most popular and robust way to do this is by using the Apache POI library for Excel and a JSON library like Jackson or Gson to parse the JSON data.

Here’s a complete guide, from a simple example to a more robust and reusable solution.
Recommended Tools & Libraries
- Apache POI: The de-facto standard for creating and manipulating Microsoft Office formats, including Excel (
.xlsx). - Jackson: A high-performance JSON processor for Java. It's widely used and has excellent features for mapping JSON to Java objects.
You'll need to add these dependencies to your project.
Step 1: Add Dependencies
For Maven (pom.xml)
<dependencies>
<!-- For creating Excel files (.xlsx) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version> <!-- Use the latest version -->
</dependency>
<!-- For parsing JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version> <!-- Use the latest version -->
</dependency>
</dependencies>
For Gradle (build.gradle)
dependencies {
// For creating Excel files (.xlsx)
implementation 'org.apache.poi:poi-ooxml:5.2.5' // Use the latest version
// For parsing JSON
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0' // Use the latest version
}
Step 2: The Java Code
We'll explore two common scenarios:
- Simple Conversion: A JSON array of objects where each object becomes a row in Excel.
- Robust Conversion: Handling more complex JSON structures (nested objects, arrays) and writing them to a single sheet.
Scenario 1: Simple JSON Array to Excel
This is the most straightforward case. Let's assume you have a JSON string that looks like this:

data.json
[
{
"id": 1,
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"age": 30
},
{
"id": 2,
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com",
"age": 25
},
{
"id": 3,
"firstName": "Peter",
"lastName": "Jones",
"email": "peter.jones@example.com",
"age": 40
}
]
Here is the Java code to convert this into an Excel file named output.xlsx.
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class JsonToExcelConverter {
public static void main(String[] args) {
// 1. JSON Input
String jsonFilePath = "data.json";
String excelFilePath = "output.xlsx";
try {
// 2. Parse JSON to a List of Maps
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, Object>> jsonData = objectMapper.readValue(new File(jsonFilePath), new TypeReference<List<Map<String, Object>>>() {});
// 3. Create Excel Workbook and Sheet
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
// 4. Create Header Row
Row headerRow = sheet.createRow(0);
// Get headers from the keys of the first map
Map<String, Object> firstRow = jsonData.get(0);
int cellIndex = 0;
for (String key : firstRow.keySet()) {
Cell cell = headerRow.createCell(cellIndex++);
cell.setCellValue(key);
}
// 5. Create Data Rows
int rowIndex = 1;
for (Map<String, Object> rowData : jsonData) {
Row row = sheet.createRow(rowIndex++);
cellIndex = 0;
for (Object value : rowData.values()) {
Cell cell = row.createCell(cellIndex++);
// Set cell value based on its type
if (value instanceof String) {
cell.setCellValue((String) value);
} else if (value instanceof Integer) {
cell.setCellValue((Integer) value);
} else if (value instanceof Double) {
cell.setCellValue((Double) value);
} else if (value instanceof Boolean) {
cell.setCellValue((Boolean) value);
} else {
cell.setCellValue(value != null ? value.toString() : "");
}
}
}
// 6. Auto-size columns for better readability
for (int i = 0; i < firstRow.size(); i++) {
sheet.autoSizeColumn(i);
}
// 7. Write the workbook to a file
try (FileOutputStream fileOut = new FileOutputStream(excelFilePath)) {
workbook.write(fileOut);
}
// 8. Close the workbook
workbook.close();
System.out.println("Excel file created successfully: " + excelFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Explanation:
- We read the
data.jsonfile. - Jackson's
objectMapperparses the JSON into aList<Map<String, Object>>. This is flexible because we don't need to create a Java class for the JSON structure. - We create a new
.xlsxworkbook usingXSSFWorkbook. - We create the header row by getting the keys from the first map in our list.
- We iterate through the list of maps and create a new row for each one, populating the cells with the values.
- We handle different Java data types (
String,Integer,Double, etc.) to ensure they are written correctly to Excel. sheet.autoSizeColumn()adjusts the column widths to fit the content.- Finally, we write the workbook to
output.xlsxand close all resources.
Scenario 2: Handling Nested JSON
Real-world JSON is often more complex. Let's consider a case with nested objects and arrays.

complex_data.json
[
{
"employeeId": "E001",
"name": "Alice Wonderland",
"contact": {
"email": "alice@example.com",
"phone": "123-456-7890"
},
"skills": ["Java", "Spring Boot", "SQL"],
"projects": [
{ "name": "Project Alpha", "role": "Lead Developer" },
{ "name": "Project Beta", "role": "Architect" }
]
},
{
"employeeId": "E002",
"name": "Bob The Builder",
"contact": {
"email": "bob@example.com",
"phone": "987-654-3210"
},
"skills": ["C#", ".NET", "Azure"],
"projects": [
{ "name": "Project Gamma", "role": "Developer" }
]
}
]
Writing this to a single sheet requires a strategy to flatten the data. A common approach is to use dot notation for nested keys and join array elements.
Here is a more advanced converter that handles this.
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class AdvancedJsonToExcelConverter {
public static void main(String[] args) {
String jsonFilePath = "complex_data.json";
String excelFilePath = "complex_output.xlsx";
try {
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, Object>> jsonData = objectMapper.readValue(new File(jsonFilePath), new TypeReference<List<Map<String, Object>>>() {});
// 1. Flatten the JSON data
List<Map<String, String>> flattenedData = new ArrayList<>();
for (Map<String, Object> employee : jsonData) {
Map<String, String> flatEmployee = flattenJsonMap(employee);
flattenedData.add(flatEmployee);
}
// 2. Create Excel Workbook and Sheet
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Employees");
// 3. Create Header Row
Row headerRow = sheet.createRow(0);
List<String> headers = new ArrayList<>(flattenedData.get(0).keySet());
for (int i = 0; i < headers.size(); i++) {
headerRow.createCell(i).setCellValue(headers.get(i));
}
// 4. Create Data Rows
int rowIndex = 1;
for (Map<String, String> rowData : flattenedData) {
Row row = sheet.createRow(rowIndex++);
for (int i = 0; i < headers.size(); i++) {
String value = rowData.get(headers.get(i));
row.createCell(i).setCellValue(value != null ? value : "");
}
}
// 5. Auto-size columns
for (int i = 0; i < headers.size(); i++) {
sheet.autoSizeColumn(i);
}
// 6. Write to file
try (FileOutputStream fileOut = new FileOutputStream(excelFilePath)) {
workbook.write(fileOut);
}
workbook.close();
System.out.println("Complex Excel file created successfully: " + excelFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Recursively flattens a JSON map.
* - Nested objects are flattened using dot notation (e.g., contact.email).
* - Arrays are joined into a single string.
*/
private static Map<String, String> flattenJsonMap(Map<String, Object> map) {
Map<String, String> flattenedMap = new java.util.LinkedHashMap<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof Map) {
// Recursively flatten nested maps
Map<String, String> nested = flattenJsonMap((Map<String, Object>) value);
for (Map.Entry<String, String> nestedEntry : nested.entrySet()) {
flattenedMap.put(key + "." + nestedEntry.getKey(), nestedEntry.getValue());
}
} else if (value instanceof List) {
// Join lists into a comma-separated string
List<?> list = (List<?>) value;
String joinedString = String.join(", ", list.stream().map(Object::toString).toArray(String[]::new));
flattenedMap.put(key, joinedString);
} else {
// Simple value
flattenedMap.put(key, value != null ? value.toString() : "");
}
}
return flattenedMap;
}
}
Explanation of Changes:
flattenJsonMapMethod: This is the core of the advanced solution. It recursively processes the map:- If a value is another
Map, it calls itself and prefixes the keys (e.g.,contactbecomescontact.email). - If a value is a
List, it joins all elements into a single string separated by commas. - Otherwise, it stores the value as a string.
- If a value is another
- Main Logic: The main method now first calls
flattenJsonMapfor each item in the JSON list to transform the complex structure into a simpleMap<String, String>. - Writing to Excel: The rest of the logic remains the same, but it now works with the flattened, simpler data structure.
Alternative: Using a Pre-defined Java Class (POJO)
If your JSON structure is fixed and known, it's often better to create a Plain Old Java Object (POJO) that matches the JSON structure. This provides type safety and cleaner code.
-
Create the POJO(s)
// Employee.java public class Employee { private String employeeId; private String name; private Contact contact; private List<String> skills; private List<Project> projects; // Getters and Setters (omitted for brevity) } // Contact.java public class Contact { private String email; private String phone; // Getters and Setters } // Project.java public class Project { private String name; private String role; // Getters and Setters } -
Modify the Conversion Code
// In your main method List<Employee> employees = objectMapper.readValue(new File("complex_data.json"), new TypeReference<List<Employee>>() {}); // Then you can access fields directly, e.g., employee.getContact().getEmail() // The writing logic would be similar but would use the POJO fields.
This approach is more maintainable for complex applications but requires more upfront boilerplate code.
