从Excel获取数据,并使用java在JSON对象的键中追加两个或多个值

xmq68pz9  于 2023-07-01  发布在  Java
关注(0)|答案(1)|浏览(156)

我的要求是从excel表中获取数据,并使用java将数据转换为嵌套的json文件。不仅仅是创建一个键,json的值类型,而是一个复杂而动态的类型,它基于输入到excel中的数据进行计算

上述数据从所附的excel应转换成下面的json。

{
    "Summary": {
        "Deposit": [
            "Contribution amt",
            "Withdrawal amt"
        ],
        "AXA Admin": [
            "Restrict Code",
            "User area"
        ]
    },
    "Coverage": {
        "Benefit Details": [
            "GMDB code",
            "Adjusted GMDB"
        ]
    }   
}

我试过了

public static JsonObject getExcelDataAsJsonObject(String excelPath) throws Exception {

        File excelFile = new File(excelPath);
        JsonObject sheetsJsonObject = new JsonObject();
        Workbook workbook = new XSSFWorkbook(excelFile);

        JsonArray sheetArray = new JsonArray();
        ArrayList<String> columnNames = new ArrayList<String>();
        Sheet sheet = workbook.getSheetAt(0);
        Iterator<Row> sheetIterator = sheet.iterator();

        while (sheetIterator.hasNext()) {

            Row currentRow = sheetIterator.next();
            JsonObject jsonObject = new JsonObject();

            // store column names
            for (int k = 0; k < currentRow.getPhysicalNumberOfCells(); k++)
                columnNames.add(currentRow.getCell(k).getStringCellValue());
            
            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)
                            continue;
                        // jsonObject.addProperty(columnNames.get(j), "");

                    } else
                        continue;
                    // jsonObject.addProperty(columnNames.get(j), "");
                }

                sheetArray.add(jsonObject);

            }
        }

        sheetsJsonObject.add(workbook.getSheetName(0), sheetArray);
        return sheetsJsonObject;

    }

上面的代码将第一行作为键,下面的行作为值,并迭代到最后一行数据。
它在控制台里打印了这个,

{"Sheet1":[{},{},{},{},{},{},{"Summary":"Coverage"},{},{},{}]}
6qftjkof

6qftjkof1#

首先,问题是如何读取以这种方式存储在Excel工作表中的数据。这种数据存储方式与电子表格数据通常存储在工作表中的方式无关。看起来好像有人试图模仿表中的JSON。这很不寻常,但就这样吧。
图纸按行存储。在您的情况下,每行可能有一个存储以下含义的单元格:

  • 如果是行中的第一个单元格,则这是级别1对象的键。
  • 如果第二个单元格在行中,那么这是2级对象的键。
  • 如果第三个单元格在行中,那么这是一个项目的水平3阵列。
  • 级别1对象将n个级别2对象的列表Map到键。
  • 2级对象将n个3级数组的列表Map到键。
  • 第3级数组中的每一个都包含n个数组项。

知道了这一点,从中生成JSON的最简单方法是使用StringBuilder来附加找到的键和/或数组项,并使用开始和结束标记来删除。要打开一个对象,需要使用“{”。要打开一个数组,使用“[”。要关闭一个对象,当另一个对象跟随时,使用“}”。若要关闭一个数组,当另一个数组跟随时,使用“]”。若要关闭一个对象,如果没有其他对象跟随,则使用“}”。若要关闭一个数组,当没有其他数组跟随时,使用“]”。数组项打开时不带标记,当后面有另一个时使用“,”关闭,当后面没有其他时不带标记。
下面的代码实现了该逻辑。生成JSON文本。
为了验证JSON是否有效,它使用org.json.JSONObject从该文本构造JSONObject

import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;

import org.json.JSONObject;

class ReadExcelToJSON {

 public static void main(String[] args) throws Exception {

  Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExample.xlsx"));
  DataFormatter dataFormatter = new DataFormatter(new java.util.Locale("en", "US"));
  // from 5.2.0 on the DataFormatter can set to use cached values for formula cells
  dataFormatter.setUseCachedValuesForFormulaCells(true);
  
  Sheet sheet = workbook.getSheetAt(0);
  Cell cell;
  String cellValue;
  
  int firstRowNum = sheet.getFirstRowNum();
  short firstCellNum = sheet.getRow(firstRowNum).getFirstCellNum();

  StringBuilder stringBuilder = new StringBuilder();
  boolean level1Open = false;
  boolean level2Open = false;
  boolean level3Open = false;
  
  stringBuilder.append("{\n");
  for (Row row : sheet) {
   cell = row.getCell(firstCellNum + 0);
   cellValue = dataFormatter.formatCellValue(cell);
   if (!"".equals(cellValue)) { //level 1 key found
    // if previous levels are open, close them
    if (level3Open) {
     stringBuilder.append("\n");
     level3Open = false;
    }    
    if (level2Open) {
     stringBuilder.append("  ]\n");
     level2Open = false;
    }
    // if same level is open, close it followed by comma, because a new one get opened now  
    if (level1Open) {
     stringBuilder.append(" },\n");
     level1Open = false;
    }    
    stringBuilder.append(" \"" + cellValue + "\": {\n");
    level1Open = true;
   } else {
    cell = row.getCell(firstCellNum + 1);
    cellValue = dataFormatter.formatCellValue(cell);
    if (!"".equals(cellValue)) { //level 2 key found
     // if previous levels are open, close them
     if (level3Open) {
      stringBuilder.append("\n");
      level3Open = false;
     }
     // if same level is open, close it followed by comma, because a new one get opened now      
     if (level2Open) {
      stringBuilder.append("  ],\n");
      level2Open = false;
     }   
     stringBuilder.append("  \"" + cellValue + "\": [\n");
     level2Open = true;
    } else {
     cell = row.getCell(firstCellNum + 2);
     cellValue = dataFormatter.formatCellValue(cell);
     if (!"".equals(cellValue)) { //level 3 array item found
      if (level3Open) {
       // if same level is open, close it followed by comma, because a new one get opened now
       stringBuilder.append(",\n");
       level3Open = false;
      }  
      stringBuilder.append("   \"" + cellValue + "\"");
      level3Open = true;
     } else {
      // empty row, do nothing
     }     
    }      
   }
  }
  // if previous levels are open, close them
  if (level3Open) {
   stringBuilder.append("\n");
   level3Open = false;
  }  
  if (level2Open) {
   stringBuilder.append("  ]\n");
   level2Open = false;
  }  
  if (level1Open) {
   stringBuilder.append(" }\n");
   level1Open = false;
  }  
  stringBuilder.append("}\n");
 
  String jsonText = stringBuilder.toString();
  System.out.println(jsonText);
  
  JSONObject jsonObject= new JSONObject(jsonText);
  System.out.println(jsonObject.toString(1));

  workbook.close();
 }
}

相关问题