This article shows you how can you convert an Excel file to JSON using Apache POI. The Apache POI is a pure java library to work with various Microsoft documents. Today we will show you the Excel to JSON Converter in java by using the POI and the Jackson JSON library. If you want to do this conversion without using Apache poi, read this article: Convert Excel file data to JSON in Javascript.
To convert excel files to JSON, we will use the below two Java libraries here:
- Apache POI – to read the excel file data.
- Jackson JSON – to parse the excel file data into JSON format.
Apache POI
Apache POI is an API provided by Apache Software Foundation for manipulating various file formats based upon Microsoft’s OLE2 Compound Document Format (OLE2) and Office Open XML standards (OOXML). Click here to know more about Apache POI. In order to work with the Apache POI library, you can use either maven dependency or poi jars.
Apache POI Maven Dependency
If you want to create a maven application, then you can add the below maven dependency into the pom.xml file.
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency>
NOTE:
If you want to work with only XLS file, then the first dependency is enough but if you want to work with both XLS or XLSX then you have to use both dependencies.
Apache POI Jars
If you are going to create a non-maven application, then you can use the below jar files directly in classpath:
- poi-4.0.1.jar
- poi-ooxml-4.0.1.jar
- poi-ooxml-schemas-4.0.1.jar
- xmlbeans-3.0.2.jar
- curvesapi-1.05.jar
- commons-codec-1.11.jar
- commons-collections4-4.2.jar
- commons-compress-1.18.jar
- commons-math3-3.6.1.jar
You can easily download all the above jars in one place: download Jars here.
If you want to know the complete Apache POI setups process in Eclipse IDE, visit another article Apache POI – Getting Started.
Jackson JSON
Jackson is a very popular, lightweight, and high-performance library in java to serialize or map java objects to JSON and vice versa. In order to use this library in the maven application, you can add the below dependency into the pom.xml file.
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.2</version> </dependency>
Excel to json converter example in Java
Here we will see an example to convert an excel file to JSON object in java using the POI and Jackson JSON library. This example program will work for both Excel file formats XLS and XLSX.
package com.javacodepoint.example; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; /** * * @author javacodepoint.com * */ public class ExcelToJSONConverter { private ObjectMapper mapper = new ObjectMapper(); /** * Method to convert excel sheet data to JSON format * * @param excel * @return */ public JsonNode excelToJson(File excel) { // hold the excel data sheet wise ObjectNode excelData = mapper.createObjectNode(); FileInputStream fis = null; Workbook workbook = null; try { // Creating file input stream fis = new FileInputStream(excel); String filename = excel.getName().toLowerCase(); if (filename.endsWith(".xls") || filename.endsWith(".xlsx")) { // creating workbook object based on excel file format if (filename.endsWith(".xls")) { workbook = new HSSFWorkbook(fis); } else { workbook = new XSSFWorkbook(fis); } // Reading each sheet one by one for (int i = 0; i < workbook.getNumberOfSheets(); i++) { Sheet sheet = workbook.getSheetAt(i); String sheetName = sheet.getSheetName(); List<String> headers = new ArrayList<String>(); ArrayNode sheetData = mapper.createArrayNode(); // Reading each row of the sheet for (int j = 0; j <= sheet.getLastRowNum(); j++) { Row row = sheet.getRow(j); if (j == 0) { // reading sheet header's name for (int k = 0; k < row.getLastCellNum(); k++) { headers.add(row.getCell(k).getStringCellValue()); } } else { // reading work sheet data ObjectNode rowData = mapper.createObjectNode(); for (int k = 0; k < headers.size(); k++) { Cell cell = row.getCell(k); String headerName = headers.get(k); if (cell != null) { switch (cell.getCellType()) { case FORMULA: rowData.put(headerName, cell.getCellFormula()); break; case BOOLEAN: rowData.put(headerName, cell.getBooleanCellValue()); break; case NUMERIC: rowData.put(headerName, cell.getNumericCellValue()); break; case BLANK: rowData.put(headerName, ""); break; default: rowData.put(headerName, cell.getStringCellValue()); break; } } else { rowData.put(headerName, ""); } } sheetData.add(rowData); } } excelData.set(sheetName, sheetData); } return excelData; } else { throw new IllegalArgumentException("File format not supported."); } } catch (Exception e) { e.printStackTrace(); } finally { if (workbook != null) { try { workbook.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * Main method to test this converter * * @param args */ public static void main(String[] args) { // Creating a file object with specific file path File excel = new File("E:/Excel/employee.xlsx"); ExcelToJSONConverter converter = new ExcelToJSONConverter(); JsonNode data = converter.excelToJson(excel); System.out.println("Excel file contains the Data:n" + data); } }
How to write JSON data into text file in java?
Now, if you want to write the converted JSON object into a file, then you can use the below method:
/** * Method to write the json data into file * * @param jsonFile * @param jsonData */ public boolean writeJsonToFile(File jsonFile, JsonNode jsonData) { try { if (jsonFile.getName().endsWith(".json")) { if (!jsonFile.exists()) { jsonFile.createNewFile(); } FileWriter fw = new FileWriter(jsonFile); fw.write(jsonData.toPrettyString()); fw.close(); return true; } else { throw new IllegalArgumentException("File should be .json file only"); } } catch (Exception e) { e.printStackTrace(); } return false; }
Conclusion
In this article, you have seen how do you Convert Excel files to JSON in java using the Apache POI and Jackson JSON libraries. If you want to do this in javascript, visit another article here: Convert Excel file data to JSON in Javascript.
You can download the above example (maven application zip) from the below download link.
FAQ
How to convert xls to JSON?
You can use the above example program to convert xls to JSON. In this case, you can use only one maven dependency which is poi-4.0.1
How to convert xlsx to JSON?
For this converter also you can use the above example program, but make sure that you use both maven dependencies (poi-4.0.1 and poi-ooxml-4.0.1).
Related Articles:
- Convert JSON to Excel in Java [Source Code]
- [Java code] Convert CSV to Excel file using Apache POI
- [Java code] Convert Excel file to CSV with Apache POI
- Apache POI – Read and Write Excel files in java
- How to write data to an existing Excel file in java?
- How to create password-protected Excel in java?
In the tutorial, Grokonez shows how to convert Excel File to JSON String or JSON File and vice versa with Java language by examples.
– Excel Files: Microsoft Excel is a spreadsheet developed by Microsoft for Windows, macOS, Android and iOS. It features calculation, graphing tools, pivot tables, and a macro programming language called Visual Basic for Applications (VBA). It has been a very widely applied spreadsheet for these platforms
– JSON stands for JavaScript Object Notation. JSON is a lightweight format for storing and transporting data. JSON is often used when data is sent from a server to a web page.
Dependencies
– org.apache.poi
: The Apache POI Project’s mission is to create and maintain Java APIs for manipulating various file formats based upon the Office Open XML standards (OOXML) and Microsoft’s OLE 2 Compound Document format (OLE2). In short, you can read and write MS Excel files using Java. In addition, you can read and write MS Word and MS PowerPoint files using Java. Apache POI is your Java Excel solution (for Excel 97-2008). We have a complete API for porting other OOXML and OLE2 formats and welcome others to participate.
– jackson-databind
: General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.5</version> </dependency>
We do 2 steps:
– Step 1: Read Excel File into Java List Objects
– Step 2: Convert Java List Objects to JSON String
-> Excel File: customers
Customer.java
: we create an Java Object class with 4 attributes: id
, name
, address
, age
package com.ozenero.convertexcel2json; public class Customer { private String id; private String name; private String address; private int age; public Customer() { } public Customer(String id, String name, String address, int age) { this.id = id; this.name = name; this.address = address; this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]"; } }
* Convert Implemetation: we do 2 steps:
– Step 1: Read Excel File into Java List Objects. We use org.apache.poi
lib to do the task.
+ Use FileInputStream
to get a Excel file.
+ Create a Excel Workbook
from FileInputStream
.
+ Get an Excel Sheet
from above Workbook
.
+ Iterate over the Sheet
. With each excel row, We get and map the cell-value with each field of Customer object and add to a Customer Object List.
+ Finally, returns all the customer list object.
– Step 2: Convert Java Objects to JSON String
+ Use ObjectMapper
to convert List Customer Objects to Json String value.
*** Note: – What is Workbook? -> In Microsoft Excel, a workbook is a collection of one or more spreadsheets, also called worksheets, in a single file.
– Details coding:
package com.ozenero.convertexcel2json; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class ConvertExcel2Json { public static void main(String[] args) { // Step 1: Read Excel File into Java List Objects List customers = readExcelFile("customers.xlsx"); // Step 2: Convert Java Objects to JSON String String jsonString = convertObjects2JsonString(customers); System.out.println(jsonString); } /** * Read Excel File into Java List Objects * * @param filePath * @return */ private static List readExcelFile(String filePath){ try { FileInputStream excelFile = new FileInputStream(new File(filePath)); Workbook workbook = new XSSFWorkbook(excelFile); Sheet sheet = workbook.getSheet("Customers"); Iterator rows = sheet.iterator(); List lstCustomers = new ArrayList(); int rowNumber = 0; while (rows.hasNext()) { Row currentRow = rows.next(); // skip header if(rowNumber == 0) { rowNumber++; continue; } Iterator cellsInRow = currentRow.iterator(); Customer cust = new Customer(); int cellIndex = 0; while (cellsInRow.hasNext()) { Cell currentCell = cellsInRow.next(); if(cellIndex==0) { // ID cust.setId(String.valueOf(currentCell.getNumericCellValue())); } else if(cellIndex==1) { // Name cust.setName(currentCell.getStringCellValue()); } else if(cellIndex==2) { // Address cust.setAddress(currentCell.getStringCellValue()); } else if(cellIndex==3) { // Age cust.setAge((int) currentCell.getNumericCellValue()); } cellIndex++; } lstCustomers.add(cust); } // Close WorkBook workbook.close(); return lstCustomers; } catch (IOException e) { throw new RuntimeException("FAIL! -> message = " + e.getMessage()); } } /** * Convert Java Objects to JSON String * * @param customers * @param fileName */ private static String convertObjects2JsonString(List customers) { ObjectMapper mapper = new ObjectMapper(); String jsonString = ""; try { jsonString = mapper.writeValueAsString(customers); } catch (JsonProcessingException e) { e.printStackTrace(); } return jsonString; } }
-> Output, we get a list of customer with Json String format:
[{"id":"1.0","name":"Jack Smith","address":"Massachusetts","age":23},{"id":"2.0","name":"Adam Johnson","address":"New York","age":27},{"id":"3.0","name":"Katherin Carter","address":"Washington DC","age":26},{"id":"4.0","name":"Jack London","address":"Nevada","age":33},{"id":"5.0","name":"Jason Bourne","address":"California","age":36}]
-> Pretty-Printed, we can see more beautiful-printed with below format:
[ { "id": "1.0", "name": "Jack Smith", "address": "Massachusetts", "age": 23 }, { "id": "2.0", "name": "Adam Johnson", "address": "New York", "age": 27 }, { "id": "3.0", "name": "Katherin Carter", "address": "Washington DC", "age": 26 }, { "id": "4.0", "name": "Jack London", "address": "Nevada", "age": 33 }, { "id": "5.0", "name": "Jason Bourne", "address": "California", "age": 36 } ]
Excel File to JSON File
We do 2 steps:
– Step 1: Read Excel File into Java List Objects, we do the same above step.
– Step 2: Write Java List Objects to JSON File. We also use the ObjectMapper
, but at the case, we write to a Json file not just return a Json String.
-> Detail Coding:
package com.ozenero.convertexcel2json; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.fasterxml.jackson.databind.ObjectMapper; public class ConvertExcel2Json { public static void main(String[] args) { // Step 1: Read Excel File into Java List Objects List customers = readExcelFile("customers.xlsx"); // Step 2: Write Java List Objects to JSON File writeObjects2JsonFile(customers, "customers.json"); System.out.println("Done"); } /** * Read Excel File into Java List Objects * * @param filePath * @return */ private static List readExcelFile(String filePath){ try { FileInputStream excelFile = new FileInputStream(new File(filePath)); Workbook workbook = new XSSFWorkbook(excelFile); Sheet sheet = workbook.getSheet("Customers"); Iterator rows = sheet.iterator(); List lstCustomers = new ArrayList(); int rowNumber = 0; while (rows.hasNext()) { Row currentRow = rows.next(); // skip header if(rowNumber == 0) { rowNumber++; continue; } Iterator cellsInRow = currentRow.iterator(); Customer cust = new Customer(); int cellIndex = 0; while (cellsInRow.hasNext()) { Cell currentCell = cellsInRow.next(); if(cellIndex==0) { // ID cust.setId(String.valueOf(currentCell.getNumericCellValue())); } else if(cellIndex==1) { // Name cust.setName(currentCell.getStringCellValue()); } else if(cellIndex==2) { // Address cust.setAddress(currentCell.getStringCellValue()); } else if(cellIndex==3) { // Age cust.setAge((int) currentCell.getNumericCellValue()); } cellIndex++; } lstCustomers.add(cust); } // Close WorkBook workbook.close(); return lstCustomers; } catch (IOException e) { throw new RuntimeException("FAIL! -> message = " + e.getMessage()); } } /** * * Convert Java Objects to JSON File * * @param customers * @param pathFile */ private static void writeObjects2JsonFile(List customers, String pathFile) { ObjectMapper mapper = new ObjectMapper(); File file = new File(pathFile); try { // Serialize Java object info JSON file. mapper.writeValue(file, customers); } catch (IOException e) { e.printStackTrace(); } } }
JSON String to Excel File
We do 2 steps:
– Convert JSON String to Java List Objects:
+ We use ObjectMapper()
and method readValue
of it to convert json string to object list.
– Write Java List Objects to Excel File, we use org.apache.poi
library:
+ Create a new Excel WorkBook.
+ Create a new Excel Sheet from WorkBook
+ Create Header Row for WorkBook
+ Iterate over Customers Object list, We map each value of customer-object with a corresponding cell of Excel row.
-> Implementation:
package com.ozenero.convertexcel2json; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class ConvertJson2Excel { public static void main(String[] args) throws IOException { // Step 1: Read JSON File to List Objects String jsonStr = "[{"id":"1","name":"Jack Smith","address":"Massachusetts","age":23},{"id":"2","name":"Adam Johnson","address":"New York","age":27},{"id":"3","name":"Katherin Carter","address":"Washington DC","age":26},{"id":"4","name":"Jack London","address":"Nevada","age":33},{"id":"5","name":"Jason Bourne","address":"California","age":36}]"; List customers = convertJsonString2Objects(jsonStr); // Step 2: Convert Java List Objects to JSON File writeObjects2ExcelFile(customers, "customers.xlsx"); } /** * * Convert JSON String to Java List Objects * * @param pathFile * @return */ private static List convertJsonString2Objects(String jsonString){ List customers = null; try { customers = new ObjectMapper().readValue(jsonString, new TypeReference>(){}); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return customers; } /** * * Write Java Object Lists to Excel File * * @param customers * @param filePath * @throws IOException */ private static void writeObjects2ExcelFile(List customers, String filePath) throws IOException { String[] COLUMNs = {"Id", "Name", "Address", "Age"}; Workbook workbook = new XSSFWorkbook(); CreationHelper createHelper = workbook.getCreationHelper(); Sheet sheet = workbook.createSheet("Customers"); Font headerFont = workbook.createFont(); headerFont.setBold(true); headerFont.setColor(IndexedColors.BLUE.getIndex()); CellStyle headerCellStyle = workbook.createCellStyle(); headerCellStyle.setFont(headerFont); // Row for Header Row headerRow = sheet.createRow(0); // Header for (int col = 0; col < COLUMNs.length; col++) { Cell cell = headerRow.createCell(col); cell.setCellValue(COLUMNs[col]); cell.setCellStyle(headerCellStyle); } // CellStyle for Age CellStyle ageCellStyle = workbook.createCellStyle(); ageCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("#")); int rowIdx = 1; for (Customer customer : customers) { Row row = sheet.createRow(rowIdx++); row.createCell(0).setCellValue(customer.getId()); row.createCell(1).setCellValue(customer.getName()); row.createCell(2).setCellValue(customer.getAddress()); Cell ageCell = row.createCell(3); ageCell.setCellValue(customer.getAge()); ageCell.setCellStyle(ageCellStyle); } FileOutputStream fileOut = new FileOutputStream(filePath); workbook.write(fileOut); fileOut.close(); workbook.close(); } }
JSON File to Excel File
– Step 1: Read JSON File into Java List Objects
– Step 2: Convert Java List Objects to Excel File
-> Implementation:
package com.ozenero.convertexcel2json; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class ConvertJson2Excel { public static void main(String[] args) throws IOException { // Step 1: Read JSON File to List Objects List customers = readJsonFile2Objects("customers.json"); // Step 2: Convert Java List Objects to JSON File writeObjects2ExcelFile(customers, "customers.xlsx"); } /** * * Convert JSON String to Java List Objects * * @param pathFile * @return */ private static List readJsonFile2Objects(String pathFile){ InputStream inJson = Customer.class.getResourceAsStream(pathFile); List customers = null; try { customers = new ObjectMapper().readValue(inJson, new TypeReference>(){}); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return customers; } /** * * Write Java Object Lists to Excel File * * @param customers * @param filePath * @throws IOException */ private static void writeObjects2ExcelFile(List customers, String filePath) throws IOException { String[] COLUMNs = {"Id", "Name", "Address", "Age"}; Workbook workbook = new XSSFWorkbook(); CreationHelper createHelper = workbook.getCreationHelper(); Sheet sheet = workbook.createSheet("Customers"); Font headerFont = workbook.createFont(); headerFont.setBold(true); headerFont.setColor(IndexedColors.BLUE.getIndex()); CellStyle headerCellStyle = workbook.createCellStyle(); headerCellStyle.setFont(headerFont); // Row for Header Row headerRow = sheet.createRow(0); // Header for (int col = 0; col < COLUMNs.length; col++) { Cell cell = headerRow.createCell(col); cell.setCellValue(COLUMNs[col]); cell.setCellStyle(headerCellStyle); } // CellStyle for Age CellStyle ageCellStyle = workbook.createCellStyle(); ageCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("#")); int rowIdx = 1; for (Customer customer : customers) { Row row = sheet.createRow(rowIdx++); row.createCell(0).setCellValue(customer.getId()); row.createCell(1).setCellValue(customer.getName()); row.createCell(2).setCellValue(customer.getAddress()); Cell ageCell = row.createCell(3); ageCell.setCellValue(customer.getAge()); ageCell.setCellStyle(ageCellStyle); } FileOutputStream fileOut = new FileOutputStream(filePath); workbook.write(fileOut); fileOut.close(); workbook.close(); } }
— Project Structure:
Xlsx2Json
A Java parser to convert xlsx sheets to JSON
Supported platforms: Anywhere you can run a Java program
Quick start
- Download release or use Gradle to make a build
- Run the command line (See Usage section)
- The json file will be generated with the same filename
Usage
java -jar xlsx2json-x.x.jar target_name «sheet_name_1 sheet_name_2 …» [true|false]
Example
java -jar xlsx2json-1.2.jar test.xlsx «monsters maps weapons» true
Arguments
- The first argument is the Excel filename
- The second argument is the sheet you want to export to json
- The third argument indicates whether show the sheet names in generated json or not, will be set to false if omitted
e.g.
ture = {«sheet1″:{…},»sheet2»:{…}
false = [{…},{…}]
Gradle build command
$ gradle clean
$ gradle fatJar
The Jar is created under the $project/build/libs/
folder.
Input file format
The first row should be column type definition (See Supported types section)
The second row should be column name definition
The following rows should be data
Especially, the first column should be Basic type so the parser could index it as the primary key
Example (Excel .xlsx file)
Monsters sheet
Integer | String | Basic | Array<Double> | Array<String> | Reference | Object |
---|---|---|---|---|---|---|
id | weapon | $flag | nums | words | shiled@shield#$id | objects |
123 | shield | TRUE | 1,2 | hello,world | 123 | a:123,b:»45″,c:false |
sword | FALSE | null | oh god | a:11;b:»22″,c:true | ||
Shields sheet
The type definition line is omitted because all columns are basic types
$id | name | forSale | price |
---|---|---|---|
123 | COPPER SHIELD | TRUE | 3600 |
Result:
{ "monsters":[ { "weapon":"shiled", "objects":{ "a":123, "b":"45", "c":false }, "words":[ "hello", "world" ], "id":123, "nums":[ 1, 2 ], "shiled":{ "forSale":true, "price":3600, "name":"COPPER SHIELD", } }, { "weapon":"sword", "objects":{ "a":11, "b":"22", "c":true }, "words":[ "oh god" ], "id":null, "nums":[ ], "shiled":null } ] }
Supported types
Basic Types
- String
- Integer
- Float
- Double
- Boolean
You can use «Basic» to let the parser automatically detect types
Especially if all columns are Basic types, you can omit the type definition row
Time Type
Support all strings with format HH:mm:ss (directly out) or cell format Time (converted to a calander object and format with simple date format)
Date Type
Support string or numeric with format yyyyMMdd and it will format as yyyy-MM-dd in the json.
DateTIme support would be added in future versions, add an issue if you need it.
Array Types
- Array<String>
- Array<Boolean>
- Array<Double>
The values should be divided using commas «,»
You can use the Array<Double> to represent all numeric types like Integer/Float and so on
Object type
- Object
Use this one to directly construct a JSON object using basic types, child should be divided using commas «,»
For more complicated objects, see Reference type
Reference type
- Reference
Use this type to insert a JSON object from another sheet, the format should be
name_of_this_column@sheet_name#column_name
and the value should be the column value of target.
Use @ to split column name and sheet name, use # to split target sheet name and target column name
Null values
- Null
If a column is blank, will automatically generate a null value in the JSON file.
Hidden columns
- $column_name
If a column’s name starts with $ sign, then it won’t appear in the result json
Especially, if you want to reference to a hidden column, you should also include the $ sign in reference column name
I want to read the excel files(.xls,.xlsx) and convert it into JSON format and save it.
Here is a code which enable me to read data from the excel file, but I am unable to get how to put data in JSON format.
Can anyone help me out.
public class ReadExcelFile {
private static XSSFWorkbook mybook;
static String fileLocation = "D://Traniee-SPG//Book1.xlsx";
public static void main(String[] args){
try{
File newFile = new File(fileLocation);
FileInputStream fIO = new FileInputStream(newFile);
mybook = new XSSFWorkbook(fIO); //finds the Excelfile
XSSFSheet mySheet = mybook.getSheetAt(0);// Return first sheet from the XLSX workbook
Iterator<Row> rowIterator = mySheet.iterator(); //create a cursor called iterator to all rows in sheet
Row r;
Cell c;
//to travel into the Excel spreadsheet
while(rowIterator.hasNext()) {
r = rowIterator.next();
//Cursor points to row
Iterator<Cell> cell_Iterator = r.cellIterator();
while(cell_Iterator.hasNext()) {
c = cell_Iterator.next();
//Cursor points to cell
switch (c.getCellType()) {
case Cell.CELL_TYPE_STRING:
System.out.print(c.getStringCellValue()+"t");
//System.out.println("Case String");
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(c.getNumericCellValue()+"t");
//System.out.println("Case number");
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(c.getBooleanCellValue()+"t");
System.out.println("Case boolean");
break;
case Cell.CELL_TYPE_FORMULA:
System.out.print(c.getCellFormula()+"t");
//System.out.println("Case formula");
break;
default:
}
}
System.out.println(" ");//next to display in table format
}
mybook.close();
fIO.close();
}
catch(FileNotFoundException ef){
ef.printStackTrace();
}
catch(IOException ei){
ei.printStackTrace();
}
}
}
peterh
11.6k18 gold badges86 silver badges104 bronze badges
asked Jun 28, 2017 at 6:28
1
answered Jun 28, 2017 at 6:37
1
Using Gson given the fact the first row in each sheet are the column names:
public static JsonObject getExcelDataAsJsonObject(File excelFile) {
JsonObject sheetsJsonObject = new JsonObject();
Workbook workbook = null;
try {
workbook = new XSSFWorkbook(excelFile);
} catch (InvalidFormatException | IOException e) {
TestLogUtils.logErrorMessage(
"ExcelUtils -> getExcelDataAsJsonObject() :: Exception thrown constructing XSSFWorkbook from provided excel file. InvalidFormatException | IOException => "
+ TestLogUtils.convertStackTraceToString(e));
}
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
JsonArray sheetArray = new JsonArray();
ArrayList<String> columnNames = new ArrayList<String>();
Sheet sheet = workbook.getSheetAt(i);
Iterator<Row> sheetIterator = sheet.iterator();
while (sheetIterator.hasNext()) {
Row currentRow = sheetIterator.next();
JsonObject jsonObject = new JsonObject();
if (currentRow.getRowNum() != 0) {
for (int j = 0; j < columnNames.size(); j++) {
if (currentRow.getCell(j) != null) {
if (currentRow.getCell(j).getCellTypeEnum() == CellType.STRING) {
jsonObject.addProperty(columnNames.get(j), currentRow.getCell(j).getStringCellValue());
} else if (currentRow.getCell(j).getCellTypeEnum() == CellType.NUMERIC) {
jsonObject.addProperty(columnNames.get(j), currentRow.getCell(j).getNumericCellValue());
} else if (currentRow.getCell(j).getCellTypeEnum() == CellType.BOOLEAN) {
jsonObject.addProperty(columnNames.get(j), currentRow.getCell(j).getBooleanCellValue());
} else if (currentRow.getCell(j).getCellTypeEnum() == CellType.BLANK) {
jsonObject.addProperty(columnNames.get(j), "");
}
} else {
jsonObject.addProperty(columnNames.get(j), "");
}
}
sheetArray.add(jsonObject);
} else {
// store column names
for (int k = 0; k < currentRow.getPhysicalNumberOfCells(); k++) {
columnNames.add(currentRow.getCell(k).getStringCellValue());
}
}
}
sheetsJsonObject.add(workbook.getSheetName(i), sheetArray);
}
return sheetsJsonObject;
}
answered Jun 26, 2018 at 5:40
package com.core.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONcellValuesect;
import org.json.simple.JSONArray;
import com.PojoClassName;
public class ReadExcelUtil {
//create pojo class based on excel sheet columns
public static List<PojoClassName> readAssetExcel(
final InputStream inputStream) {
List<PojoClassName> cellValues = new ArrayList<PojoClassName>();
XSSFWorkbook workbook;
try {
workbook = new XSSFWorkbook(inputStream);
XSSFSheet sheet = workbook.getSheetAt(0);
cellValues = damcellValues(sheet, cellValues);
return cellValues;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cellValues;
}
private static List<PojoClassName> damcellValues(XSSFSheet sheet,
List<PojoClassName> cellValues) {
int num = sheet.getPhysicalNumberOfRows();
for (int i = 1; i <= num; i++) {
Row column = sheet.getRow(i);
if (column.getCell(0) == null) {
break;
}
PojoClassName object = new PojoClassName();
String str1 = column.getCell(0).getStringCellValue();
object.setDamPath(str1);
String str2 = column.getCell(1).getStringCellValue();
object.setServerUrl(str2);
String str3 = column.getCell(2).getStringCellValue();
object.setAssetTitle(str3);
String str4 = column.getCell(3).getStringCellValue();
object.setAssetDescription(str4);
String str5 = column.getCell(4).getStringCellValue();
object.setSourceId(str5);
cellValues.add(object);
}
return cellValues;
}
//you can use below method to convert the List into Json
public static String getJsonFromMyFormObject(List<DamAssetDetails> obj) throws JSONException{
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < obj.size(); i++)`enter code here`
{
JSONObject formDetailsJson = new JSONObject();
formDetailsJson.put("key1", obj.get(i).getDamPath());
formDetailsJson.put("key2", obj.get(i).getServerUrl());
formDetailsJson.put("key3", obj.get(i).getAssetTitle());
formDetailsJson.put("key4", obj.get(i).getAssetDescription());
formDetailsJson.put("key5", obj.get(i).getSourceId());
jsonArray.add(formDetailsJson);
}
//responseDetailsJson.put("obj", jsonArray);
return jsonArray.toJSONString();
}
}
answered Jun 30, 2017 at 7:21
public static String ExcelReader(String filePath, int index) throws IOException {
List<String> list = new ArrayList<String>();
try {
FileInputStream excelFile = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet datatypeSheet = workbook.getSheetAt(index);
XSSFRow row = (XSSFRow) datatypeSheet.getRow(0);
String TC_ID = String.valueOf(row.getCell(0));
String TS_ID = String.valueOf(row.getCell(1));
String Test_Steps = String.valueOf(row.getCell(2));
String Execution_Flag = String.valueOf(row.getCell(3));
String IdentifierType = String.valueOf(row.getCell(4));
String IdentifierValue = String.valueOf(row.getCell(5));
String Action_Keyword = String.valueOf(row.getCell(6));
String Dataset = String.valueOf(row.getCell(7));
for (int rowNumber = 1; rowNumber <= datatypeSheet.getLastRowNum(); rowNumber++) {
list.add(jsonObject.toString());
XSSFRow row1 = (XSSFRow) datatypeSheet.getRow(rowNumber);
for (int columnNumber = 0; columnNumber < row.getLastCellNum(); columnNumber++) {
String cell = String.valueOf(row1.getCell(columnNumber));
if (cell != null) {
switch (columnNumber) {
case 0:
jsonObject.addProperty(*** cell);
break;
case 1:
jsonObject.addProperty(**, cell);
break;
case 2:
jsonObject.addProperty(**, cell);
break;
}
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
json = gson.toJson(jsonObject);
System.out.print(json);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonObject.toString();
}
}
answered Jun 18, 2019 at 10:23
1
Refer below code for Excel to Json Conversion —
multiple sheets also handled and read the excel-sheet values on row by row (first row is consider as a key and remaining rows are Values in json format) sample input and outputs are attached here inputFile-Sheet1
inputFile-Sheet2
output jsonobject.
public class ExcelToJsonConvertor {
private JSONObject readExcelFileAsJsonObject_RowWise(String filePath) {
DataFormatter dataFormatter = new DataFormatter();
JSONObject workbookJson = new JSONObject();
JSONArray sheetJson = new JSONArray();
JSONObject rowJson = new JSONObject();
try {
FileInputStream excelFile = new FileInputStream(new File(filePath));
Workbook workbook = new XSSFWorkbook(excelFile);
FormulaEvaluator formulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
for (Sheet sheet : workbook) {
sheetJson = new JSONArray();
int lastRowNum = sheet.getLastRowNum();
int lastColumnNum = sheet.getRow(0).getLastCellNum();
Row firstRowAsKeys = sheet.getRow(0); // first row as a json keys
for (int i = 1; i <= lastRowNum; i++) {
rowJson = new JSONObject();
Row row = sheet.getRow(i);
if (row != null) {
for (int j = 0; j < lastColumnNum; j++) {
formulaEvaluator.evaluate(row.getCell(j));
rowJson.put(firstRowAsKeys.getCell(j).getStringCellValue(),
dataFormatter.formatCellValue(row.getCell(j), formulaEvaluator));
}
sheetJson.add(rowJson);
}
}
workbookJson.put(sheet.getSheetName(), sheetJson);
}
} catch (Exception e) {
e.printStackTrace();
}
return workbookJson;
}
public static void main(String arg[]) {
ExcelToJsonConvertor excelConvertor = new ExcelToJsonConvertor();
String filePath = "C:\Users\username\Documents\WorkInputFiles\InputSheet.xlsx";
JSONObject data = excelConvertor.readExcelFileAsJsonObject_RowWise(filePath);
System.out.println(data);
}
}
Maven dependencies needed — json-simple, apache.poi, poi-ooxml
answered Dec 17, 2020 at 22:13
A reader of the article Read / Write Excel Data Using Apache POI asks me a question about how to read excel sheet data and write those data to a JSON file. This question lead to this example. So after reading this article you can know how to convert excel sheet data to a JSON file, and how to create a text file that contains the excel sheet data.
1. Convert Excel To JSON Example Required Library.
This example requires the below jar files, you can go to the maven repository to search and download them if you add the jars by hand. You can read the article How To Download Jars From Maven Repository to learn more.
- commons-beanutils-1.8.3.jar
- ezmorph-1.0.6.jar
- commons-collections-3.2.1.jar
- commons-lang-2.6.jar
- json-lib-2.4.jar
- apache-poi-maven-lib
- poi-bin-3.16-20170419.zip
Because this example uses apache poi to parse excel files, so all the poi-related jar files are included in the poi-bin zip file. Just download it and unzip it to get those jars.
2. Convert Excel To JSON Example Source Code.
- Below is the example source code that can convert an excel file to a JSON file.
package com.dev2qa.java.basic.excel; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Header; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.openqa.selenium.json.Json; import com.google.gson.Gson; import com.google.gson.stream.JsonReader; import net.sf.json.JSONObject; public class ReadExcelDataWithDynamicColumn { public static void main(String[] args) { // You can specify your excel file path. String excelFilePath = "/Users/zhaosong/Documents/WorkSpace/EmployeeInfo.xls"; // This method will read each sheet of data from the above excel file and create a JSON and a text file to save the sheet data. creteJSONAndTextFileFromExcel(excelFilePath); } /* Read data from an excel file and output each sheet of data to a JSON file and a text file. * filePath: The excel file store path. * */ private static void creteJSONAndTextFileFromExcel(String filePath) { try{ /* First need to open the file. */ FileInputStream fInputStream = new FileInputStream(filePath.trim()); /* Create the workbook object to access excel file. */ //Workbook excelWookBook = new XSSFWorkbook(fInputStream) /* Because this example use .xls excel file format, so it should use HSSFWorkbook class. For .xlsx format excel file use XSSFWorkbook class.*/; Workbook excelWorkBook = new HSSFWorkbook(fInputStream); // Get all excel sheet count. int totalSheetNumber = excelWorkBook.getNumberOfSheets(); // Loop in all excel sheet. for(int i=0;i<totalSheetNumber;i++) { // Get current sheet. Sheet sheet = excelWorkBook.getSheetAt(i); // Get sheet name. String sheetName = sheet.getSheetName(); if(sheetName != null && sheetName.length() > 0) { // Get current sheet data in a list table. List<List<String>> sheetDataTable = getSheetDataList(sheet); // Generate JSON format of above sheet data and write to a JSON file. String jsonString = getJSONStringFromList(sheetDataTable); String jsonFileName = sheet.getSheetName() + ".json"; writeStringToFile(jsonString, jsonFileName); // Generate text table format of above sheet data and write to a text file. String textTableString = getTextTableStringFromList(sheetDataTable); String textTableFileName = sheet.getSheetName() + ".txt"; writeStringToFile(textTableString, textTableFileName); } } // Close excel work book object. excelWorkBook.close(); }catch(Exception ex){ System.err.println(ex.getMessage()); } } /* Return sheet data in a two-dimensional list. * Each element in the outer list is represent a row, * each element in the inner list represent a column. * The first row is the column name row.*/ private static List<List<String>> getSheetDataList(Sheet sheet) { List<List<String>> ret = new ArrayList<List<String>>(); // Get the first and last sheet row number. int firstRowNum = sheet.getFirstRowNum(); int lastRowNum = sheet.getLastRowNum(); if(lastRowNum > 0) { // Loop in sheet rows. for(int i=firstRowNum; i<lastRowNum + 1; i++) { // Get current row object. Row row = sheet.getRow(i); // Get first and last cell number. int firstCellNum = row.getFirstCellNum(); int lastCellNum = row.getLastCellNum(); // Create a String list to save column data in a row. List<String> rowDataList = new ArrayList<String>(); // Loop in the row cells. for(int j = firstCellNum; j < lastCellNum; j++) { // Get current cell. Cell cell = row.getCell(j); // Get cell type. int cellType = cell.getCellType(); if(cellType == CellType.NUMERIC.getCode()) { double numberValue = cell.getNumericCellValue(); // BigDecimal is used to avoid double values is counted using the Scientific counting method. // For example the original double variable value is 12345678, but JDK translated the value to 1.2345678E7. String stringCellValue = BigDecimal.valueOf(numberValue).toPlainString(); rowDataList.add(stringCellValue); }else if(cellType == CellType.STRING.getCode()) { String cellValue = cell.getStringCellValue(); rowDataList.add(cellValue); }else if(cellType == CellType.BOOLEAN.getCode()) { boolean numberValue = cell.getBooleanCellValue(); String stringCellValue = String.valueOf(numberValue); rowDataList.add(stringCellValue); }else if(cellType == CellType.BLANK.getCode()) { rowDataList.add(""); } } // Add current row data list in the return list. ret.add(rowDataList); } } return ret; } /* Return a JSON string from the string list. */ private static String getJSONStringFromList(List<List<String>> dataTable) { String ret = ""; if(dataTable != null) { int rowCount = dataTable.size(); if(rowCount > 1) { // Create a JSONObject to store table data. JSONObject tableJsonObject = new JSONObject(); // The first row is the header row, store each column name. List<String> headerRow = dataTable.get(0); int columnCount = headerRow.size(); // Loop in the row data list. for(int i=1; i<rowCount; i++) { // Get current row data. List<String> dataRow = dataTable.get(i); // Create a JSONObject object to store row data. JSONObject rowJsonObject = new JSONObject(); for(int j=0;j<columnCount;j++) { String columnName = headerRow.get(j); String columnValue = dataRow.get(j); rowJsonObject.put(columnName, columnValue); } tableJsonObject.put("Row " + i, rowJsonObject); } // Return string format data of JSONObject object. ret = tableJsonObject.toString(); } } return ret; } /* Return a text table string from the string list. */ private static String getTextTableStringFromList(List<List<String>> dataTable) { StringBuffer strBuf = new StringBuffer(); if(dataTable != null) { // Get all row count. int rowCount = dataTable.size(); // Loop in the all rows. for(int i=0;i<rowCount;i++) { // Get each row. List<String> row = dataTable.get(i); // Get one row column count. int columnCount = row.size(); // Loop in the row columns. for(int j=0;j<columnCount;j++) { // Get column value. String column = row.get(j); // Append column value and a white space to separate value. strBuf.append(column); strBuf.append(" "); } // Add a return character at the end of the row. strBuf.append("rn"); } } return strBuf.toString(); } /* Write string data to a file.*/ private static void writeStringToFile(String data, String fileName) { try { // Get the currently executing class working directory. String currentWorkingFolder = System.getProperty("user.dir"); // Get file path separator. String filePathSeperator = System.getProperty("file.separator"); // Get the output file absolute path. String filePath = currentWorkingFolder + filePathSeperator + fileName; // Create File, FileWriter, and BufferedWriter object. File file = new File(filePath); FileWriter fw = new FileWriter(file); BufferedWriter buffWriter = new BufferedWriter(fw); // Write string data to the output file, flush and close the buffered writer object. buffWriter.write(data); buffWriter.flush(); buffWriter.close(); System.out.println(filePath + " has been created."); }catch(IOException ex) { System.err.println(ex.getMessage()); } } }
Недавно нужно было написать API автотесты — запросы Post с большим количеством параметров в теле, в том числе вложенные JSON объекты, массивы , массивы JSON объектов. Многие параметры не обязательные, а значит — большое количество наборов тестовых данных.
Дано: Датапровайдер — для многократного запуска тестов, тестовые данные в таблице Excel.
Что бы сформировать тело первого запроса пришлось создать несколько классов, через сеттеры присваивать значения переменным в классе и из базового класса формировать JSON, который и использовался как тело запроса. И вдруг оказалось, что все написанное никак не получится переиспользовать для других эндпоинтов. Тогда и решил написать метод, который будет превращать таблицу Excel в JSON объект без всяких там классов и правок в коде. Нужно только придерживаться некоторых правил при составлении таблицы.
Итак! Для получения данных из таблицы использовал, как обычно, Fillo. Название столбца будет ключом, значения в столбце, собственно, значениями ключа в запросе. Строка таблицы — один набор тестовых данных.
Должно быть как-то так на входе:
shop_name |
сity |
shop#1 |
Charkiv |
shop#2 |
Kyiv |
shop#3 |
Dnipro |
На выходе:
[{"shop_name": "shop#1", "сity": "Charkiv"},
{"shop_name": "shop#2", "сity": "Kyiv"},
{"shop_name": "shop#3", "сity": "Dnipro"}]
Для начала, метод для получения ВСЕХ данных из Excel листа в виде массива мапов. Раньше использовал для похожих задач для вебтестов. Метод принимает две строки: путь к Excel файлу и название листа. Это единственные константы, которые вам придется захардкодить, все остальное управление формированием тела запроса выполняется из Excel файла. Я создаю для этого класс констант и там, если необходимо, меняю значение, которое потом используется во всех тестах.
Hidden text
public List fromExcelToListOfMaps (String docPath, String sheet) {
PATH_TO_EXCEL_DOC = docPath;
Fillo fillo = new Fillo();
Connection connection;
List<Map<String, String>> listOfMaps = new ArrayList<>();
try {
/* getting all the data from excel file */
connection = fillo.getConnection(PATH_TO_EXCEL_DOC);
Recordset recordset = connection.executeQuery("Select * From "
+sheet+" ");
/* getting column names*/
ArrayList<String> keys = recordset.getFieldNames();
int size = keys.size();
/* creating array of maps*/
while (recordset.next()) {
Map<String, String> values = new LinkedMap<>();
for (int i = 0; i <size; i++) {
String key = keys.get(i);
String value = recordset.getField(key);
values.put(key, value);
}
listOfMaps.add(values);
}
recordset.close();
connection.close();
} catch (FilloException e) {
e.printStackTrace();
}
return listOfMaps;
}
результат:
[{shop_name=shop#1, сity=Charkiv}, {shop_name=shop#2, сity=Kyiv}, {shop_name=shop#3, сity=Dnipro}]
Превратить мапу в JSON с помощью GSON можно за одно действие, но тут оказалось, что сервер не принимает пустые ключи, поэтому их нужно выпилить в процессе. Следующий метод принимает на вход массив из метода fromExcelToListOfMaps , удаляет ключи без значений и возвращает массив JSON строк.
public List<String> dataToListOfJson(List<Map<String, String>> listOfMaps){
Gson gson = new Gson();
List<String> listOfJson = new ArrayList<>();
for (int i=0; i<listOfMaps.size(); i++) {
/*
* getting each map collection
* */
Map<String,String> row = listOfMaps.get(i);
/*
* deleting empty values
*/
row.entrySet().removeIf(y -> (y.getValue().equals("")));
/*
* Turn map without empty fields to json
*/
String requestBody = gson.toJson(row);
listOfJson.add(requestBody);
}
return listOfJson;
}
На входе:
shop_name |
сity |
shop#1 |
Charkiv |
Kyiv |
|
shop#3 |
После первого метода:
[{shop_name=shop#1, сity=Charkiv},
{shop_name=, сity=Kyiv},
{shop_name=shop#3, сity=}]
На выходе:
[{«shop_name»:»shop#1″,»сity»:»Charkiv»},
{«сity»:»Kyiv»},
{«shop_name»:»shop#3″}]
В таком виде уже можно отправлять результат в датапровайдер, но у меня значения не только типа String. А как объяснить методу, что вот это вот boolean, а вот это Integer и кавычки тут не нужны, а там вообще массив JSON объектов. И в коде указывать нельзя, получится не универсально. Решил в название столбцов добавить ключевые слова:
-
string — нет ключевого слова
-
boolean — bool
-
float — flo
-
int — int
Ключевое слово отделяется от имени ключа двумя звездочками (**). Теперь, после проверки на пустые значения, выполняется проверка на наличия ключевого слова в названии столбца, и, если это слово есть и соответствует одному из приведенных выше, создается новый ключ (отбрасывается ключевое слово и звездочки) и ему присваивается значение с приведением к нужному типу данных. Выглядит примерно так:
public static final String FLOAT_VAL = "flo";
public static final String BOOLEAN_VAL = "bool";
/*work with Float*/
else if (keyWord.equals(FLOAT_VAL)){
value = value.replace(",", ".");
JsonElement a = gson.toJsonTree(Float.parseFloat(value));
jsElemMap.add(key.substring(x+2), a);
}
/*work with Boolean*/
else if (keyWord.equals(BOOLEAN_VAL)){
JsonElement a = gson.toJsonTree(Boolean.parseBoolean(value));
jsElemMap.add(key.substring(x+2), a);
после чего из мапы выпиливаются все пары в ключе которых присутствуют ** . Т.е. если написать в таблице ключевое слово с ошибкой, то эта колонка в запрос не попадет.
В результате
На входе:
shop_name |
сity |
Int**employee_qty |
Bool**Sunday_off |
shop#1 |
Charkiv |
3 |
true |
shop#2 |
Kyiv |
3 |
true |
shop#3 |
Dnipro |
2 |
false |
на выходе:
[{"shop_name":"shop#1","сity":"Charkiv","employee_qty":3,"Sunday_off":true}, {"shop_name":"shop#2","сity":"Kyiv","employee_qty":3,"Sunday_off":true}, {"shop_name":"shop#3","сity":"Dnipro","employee_qty":2,"Sunday_off":false}]
Конечно работать с разными типами данных в Map<String, String> не получится, поэтому все результаты пересобираются в переменную типа JsonObject.
Дальше нужно было добавить ключи со значениями класса JsonObject. Конечно можно просто в Excel ячейку записать что-то типа {«salary»: 25.0,»bonus»: 4.75}, но ведь у меня уже есть метод, который который соберет JSON из листа Excel. Нужно только указать лист и строку которая будет использоваться. Получилось чуть-чуть рекурсии. Ключевое слово:
-
JsonObject — Если в качестве значения ключа нужен JsonObject, то ключевое слово должно совпадать с названием Excel листа, из которого берутся данные (добавил метод получающий все имена листов Excel файла в массив). Значение в ячейке (тип int) — номер строки в этом листе (нумерация с нуля).
/*work with JsonObjects */
/*If Excel file contains sheet which name equals keyWord */
else if (excelSheetNames(PATH_TO_EXCEL_DOC).contains(keyWord)){
/*get this sheet as list of json*/
List aa = dataToListOfJson2(fromExcelToListOfMaps(PATH_TO_EXCEL_DOC,keyWord));
/*and add one of json as value of current key*/
jsElemMap.add(key.substring(x+2), gson.toJsonTree(aa.get(Integer.parseInt(value))));
}
В результате на входе:
На выходе:
[{"Id":0,"First_Name":"Wasja","Last_Name":"Smith","Age":19,"Gender":"m","paycheck":{"salary":20.0}}, {"Id":1,"First_Name":"Tanja","Last_Name":"Johnson","Age":25,"Gender":"f","paycheck":{"salary":20.0}}, {"Id":250,"First_Name":"Ighor","Last_Name":"Williams","Age":42,"Gender":"m","paycheck":{"salary":25.0,"bonus":4.75}}, {"Id":13,"First_Name":"Masha","Last_Name":"Brown","Age":19,"Gender":"f","paycheck":{"salary":25.0,"bonus":4.75}}, {"Id":4,"First_Name":"Olja","Last_Name":"Davis","Age":18,"Gender":"f","paycheck":{"salary":33.3,"bonus":5.8}}, {"Id":40,"First_Name":"Oleg","Last_Name":"Miller","Age":25,"Gender":"m","paycheck":{"bonus":100.0}}, {"Id":6,"First_Name":"Kolja","Last_Name":"Wilson","Age":21,"Gender":"m","paycheck":{"salary":33.3,"bonus":5.8}}, {"Id":7,"First_Name":"Andrew","Last_Name":"Moore","Age":20,"Gender":"m","paycheck":{"salary":25.0,"bonus":4.75}}]
Остались массивы. Наверное, стоило написать логику с нуля, но я поленился и решил из JsonObject и выбранной строки просто все значения перенести в List<Object> . Написал отдельный метод. На вход принимает путь к Excel файлу, имя листа и номер строки (нумерация с нуля)
public List arrayVal(String pathToExcel, String sheetName, int rowNumber){
List<JsonObject> x = dataToListOfJson2(fromExcelToListOfMaps(pathToExcel, sheetName));
JsonObject dataForArray = x.get(rowNumber);
List<Object> arr= new LinkedList<>();
for(String key : dataForArray.keySet()){
arr.add(dataForArray.get(key));
}
return arr;
}
Ключевое слово:
-
List<Object> — arr. Имя столбца должно совпадать с именем Excel листа, из которого будут браться значения для массива. Значение в ячейке (тип int) — номер строки. Имя столбцов в Excel листе из которого будут набираться данные в массив значения не имеют, но они не должны повторяться (Fillo не обработает) и для всех столбцов должно быть одинаковое ключевое слово. (для данных типа String ключевое слово не нужно).
В результате как-то так на входе:
На выходе:
[{"shop_name":"shop#1","сity":"Charkiv","income_per_month":[78500,22222,2222,159]}, {"shop_name":"shop#2","сity":"Kyiv","income_per_month":[56900,11111,987456,6423,98741]}, {"shop_name":"shop#3","сity":"Dnipro","income_per_month":[12694,33333,111111]}]
Вот основной класс с методами:
Hidden text
package api;
import com.codoid.products.exception.FilloException;
import com.codoid.products.fillo.Connection;
import com.codoid.products.fillo.Fillo;
import com.codoid.products.fillo.Recordset;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.commons.collections4.map.LinkedMap;
import java.util.*;
import static api.ApiConstants.ApiBodyConstants.*;
import static jdk.nashorn.internal.objects.NativeString.toLowerCase;
public class ApiBase {
public static String PATH_TO_EXCEL_DOC = "";
public List fromExcelToListOfMaps (String docPath, String sheet) {
PATH_TO_EXCEL_DOC = docPath;
Fillo fillo = new Fillo();
Connection connection;
List<Map<String, String>> listOfMaps = new ArrayList<>();
try {
/* getting all the data from excel file */
connection = fillo.getConnection(docPath);
Recordset recordset = connection.executeQuery("Select * From "
+sheet+" ");
/* getting column names*/
ArrayList<String> keys = recordset.getFieldNames();
int size = keys.size();
/* creating array of maps*/
while (recordset.next()) {
Map<String, String> values = new LinkedMap<>();
for (int i = 0; i <size; i++) {
String key = keys.get(i);
String value = recordset.getField(key);
values.put(key, value);
}
listOfMaps.add(values);
}
recordset.close();
connection.close();
} catch (FilloException e) {
e.printStackTrace();
}
return listOfMaps;
}
public List<String> dataToListOfJson(List<Map<String, String>> listOfMaps){
Gson gson = new Gson();
List<String> listOfJson = new ArrayList<>();
for (int i=0; i<listOfMaps.size(); i++) {
/*
* getting each map collection
* */
Map<String,String> row = listOfMaps.get(i);
/*
* deleting empty values
*/
row.entrySet().removeIf(y -> (y.getValue().equals("")));
/*deleting empty values in a longer way*/
// for (Map.Entry<String, String> entry: row.entrySet()) {
// String key = entry.getKey();
// String value = entry.getValue();
// if(value.equals("")){
// row.remove(key);
// }
// }
/*
* Turn map without empty fields to json
*/
String requestBody = gson.toJson(row);
listOfJson.add(requestBody);
}
return listOfJson;
}
public List<JsonObject> dataToListOfJson2(List<Map<String, String>> listOfMaps){
Gson gson = new Gson();
List<JsonObject> listOfJson = new ArrayList<>();
for (int i=0; i<listOfMaps.size(); i++) {
/*
* getting each map collection
* */
Map<String,String> row = listOfMaps.get(i);
JsonObject jsElemMap = new JsonObject();
/*
* deleting keys that have empty values
*/
row.entrySet().removeIf(y -> (y.getValue().equals("")));
/*iteration map to change value classes and add them to json object */
for (Map.Entry<String, String> entry: row.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (key.indexOf("**")>0) {
int x = key.indexOf("**");
String keyWord = toLowerCase(key.substring(0, x));
/*work with Integer*/
if (keyWord.equals(INT_VAL)){
JsonElement a = gson.toJsonTree(Integer.parseInt(value));
jsElemMap.add(key.substring(x+2), a);
}
/*work with Float*/
else if (keyWord.equals(FLOAT_VAL)){
value = value.replace(",", ".");
JsonElement a = gson.toJsonTree(Float.parseFloat(value));
jsElemMap.add(key.substring(x+2), a);
}
/*work with Boolean*/
else if (keyWord.equals(BOOLEAN_VAL)){
JsonElement a = gson.toJsonTree(Boolean.parseBoolean(value));
jsElemMap.add(key.substring(x+2), a);
}
/*work with array*/
else if (keyWord.equals(ARRAY_VAL)&& excelSheetNames(PATH_TO_EXCEL_DOC).contains(key.substring(x+2))){
List arr = arrayVal(PATH_TO_EXCEL_DOC, key.substring(x+2), Integer.parseInt(value));
JsonElement a = gson.toJsonTree(arr);
jsElemMap.add(key.substring(x+2), a);
}
/*work with JsonObjects */
/*If Excel file contains sheet which name equals keyWord */
else if (excelSheetNames(PATH_TO_EXCEL_DOC).contains(keyWord)){
/*get this sheet as list of json*/
List aa = dataToListOfJson2(fromExcelToListOfMaps(PATH_TO_EXCEL_DOC,keyWord));
/*and add one of json as value of current key*/
jsElemMap.add(key.substring(x+2), gson.toJsonTree(aa.get(Integer.parseInt(value))));
}
}else{
/*If there is no keyWord*/
jsElemMap.add(key, gson.toJsonTree(value) );
}
}
/* remove all keys with keyword */
row.entrySet().removeIf(y -> (y.getKey().contains("**")));
/*
* Turn map without empty fields to json
*/
listOfJson.add(jsElemMap);
}
return listOfJson;
}
public List arrayVal(String pathToExcel, String sheetName, int rowNumber){
List<JsonObject> x = dataToListOfJson2(fromExcelToListOfMaps(pathToExcel, sheetName));
JsonObject dataForArray = x.get(rowNumber);
List<Object> arr= new LinkedList<>();
for(String key : dataForArray.keySet()){
arr.add(dataForArray.get(key));
}
return arr;
}
/*getting names of sheets to list*/
public List<String> excelSheetNames(String filePath){
Fillo fillo = new Fillo();
Connection connection =null;
List<String> names = new ArrayList<>();
try {
connection = fillo.getConnection(filePath);
names = connection.getMetaData().getTableNames();
connection.close();
} catch (FilloException filloException) {
connection.close();
filloException.printStackTrace();
}
return names;
}
}
В общем по функционалу на этом все, осталось заполнить таблицу. Оказалось, что указывать номера строк, находящихся на другом листе, не очень-то и удобно, постоянно какая-то путаница. Тут мне на помощь пришли неправильные ключевые слова. Если в имени столбца присутствует две звездочки (**), но текст перед ** не соответствует одному из ключей, то этот столбец в запросе игнорируется, и в него можно писать комментарии, добавлять нумерацию, или выводить результаты теста. Я ставил четыре звездочки, чтобы сходу видеть, что в запрос не попадет. Таблицы стали выглядеть как-то так:
int**Id |
First_Name |
Last_Name |
int**Age |
Gender |
pay**paycheck |
com****coment |
0 |
Wasja |
Smith |
19 |
m |
0 |
<— Point off row****number from the sheet pay |
1 |
Tanja |
Johnson |
25 |
f |
0 |
|
2 |
Ighor |
Williams |
42 |
m |
1 |
|
3 |
Masha |
Brown |
19 |
f |
1 |
|
4 |
Olja |
Davis |
18 |
f |
3 |
|
5 |
Oleg |
Miller |
25 |
m |
4 |
|
6 |
Kolja |
Wilson |
21 |
m |
3 |
|
7 |
Andrew |
Moore |
20 |
m |
1 |
row****numb |
flo**salary |
flo**bonus |
0 |
20 |
|
1 |
25 |
4,75 |
2 |
22 |
4 |
3 |
33,3 |
5,8 |
4 |
100 |
Осталось передать все это в датапровайдер и превратить в классический двухмерный массив строк.
@DataProvider(name = "Request2")
public Object[][] request2() {
List<JsonObject> listOfJson = base.dataToListOfJson2(base
.fromExcelToListOfMaps(PATH_TO_EXCEL_DOC,SHEET_NAME));
String[][] arrayOfJson = new String[listOfJson.size()][1];
for(int i = 0; i< listOfJson.size(); i++){
arrayOfJson[i][0] = listOfJson.get(i).toString();
}
return arrayOfJson;
}
И дальше в тест:
@Test(dataProvider = "Request2")
public void exampleTest1_3 (String request){
given()
.spec(requestPostEvents(request))
.when()
.log().body()
.post();
}
Тело первого теста:
Hidden text
Body:
{
«shop_name»: «shop#1»,
«сity»: «Charkiv»,
«income_per_month»: [
78500,
22222,
2222,
159
],
«employee_qty»: 3,
«employees»: [
{
«Id»: 0,
«First_Name»: «Wasja»,
«Last_Name»: «Smith»,
«Age»: 19,
«Gender»: «m»,
«paycheck»: {
«salary»: 20.0
}
},
{
«Id»: 1,
«First_Name»: «Tanja»,
«Last_Name»: «Johnson»,
«Age»: 25,
«Gender»: «f»,
«paycheck»: {
«salary»: 20.0
}
},
{
«Id»: 2,
«First_Name»: «Ighor»,
«Last_Name»: «Williams»,
«Age»: 42,
«Gender»: «m»,
«paycheck»: {
«salary»: 25.0,
«bonus»: 4.75
}
}
],
«work_time»: «09,00-18,00»,
«Sunday_off»: true,
«goods»: {
«tobacco»: true,
«alcohol»: true,
«groshery»: true,
«weapons»: false,
«drugs»: false
}
}
Теперь, в случае если будут добавлены, удалены или изменены параметры, или тестовые данные, мне даже не нужно будет заглядывать в код, только подправить табличку. Как и все универсальное, в обращении не очень удобно, но привыкнуть можно.
Все это писалось в отдельном проекте, клонировать можно здесь.
Можно подправить файл Data.xlsx под ваши нужды и позапускать тесты из класса ExampleTests , что бы посмотреть, получите ли вы то, что вам нужно. Если вы начинаете новый проект с API (+WEB) тестами, это можно использовать как шаблон.
Если нужно применить в существующем проекте, но совсем не хочется разбираться как это устроено, то скопируйте пакеты api и файл Data.xlsx в соответствующие разделы вашего проекта на Maven + TestNG, при необходимости добавьте нужные зависимости и пишите тесты в классе ExampleTests.
Собираюсь потихоньку перетянуть сюда все универсальные методы, которые использовал — пусть все лежит в одном месте! Надеюсь, что информация поможет другим начинающим автоматизаторам).