【问题标题】:Converting an CSV file to a JSON object in Java在 Java 中将 CSV 文件转换为 JSON 对象
【发布时间】:2012-03-01 21:12:17
【问题描述】:

是否有一个开源 java 库可以将 CSV(或 XLS)文件转换为 JSON 对象?

我尝试使用json.cdl,但不知何故它似乎不适用于大型 CSV 字符串。

我正在尝试找到类似 http://www.cparker15.com/code/utilities/csv-to-json/ 的东西,但它是用 Java 编写的。

【问题讨论】:

  • 可能不是完全重复,因为它专门要求 Java 解决方案。
  • OpenCSV 是一个非常好的处理 .csv 的库:baeldung.com/opencsv - 您可以使用它从文件中获取 POJO,然后相当容易地将其序列化为另一种格式。

标签: java json csv xls


【解决方案1】:

我在这段代码中使用了 excel 文件。你可以使用 csv。 我已经为我所知道的特定 Excel/csv 格式编写了这个类。

import java.io.File;

public class ReadExcel {

    private String inputFile;

    public void setInputFile(String inputFile) {
        this.inputFile = inputFile;
    }

    public void read() throws IOException {
        File inputWorkbook = new File(inputFile);
        Workbook w;
        try {
            w = Workbook.getWorkbook(inputWorkbook);
            // Get the first sheet
            Sheet sheet = w.getSheet(0);
            // Loop over first 10 column and lines
            int columns = sheet.getColumns();
            int rows = sheet.getRows();
            ContactList clist = new ContactList();
            ArrayList<Contact> contacts = new ArrayList<Contact>();
            for (int j = 1; j < rows; j++) {
                Contact contact = new Contact();
                for (int i = 0; i < columns; i++) {
                    Cell cell = sheet.getCell(i, j);

                    switch (i) {
                    case 0:
                        if (!cell.getContents().equalsIgnoreCase("")) {
                            contact.setSrNo(Integer.parseInt(cell.getContents()));
                        } else {
                            contact.setSrNo(j);
                        }

                        break;
                    case 1:
                        contact.setName(cell.getContents());
                        break;
                    case 2:
                        contact.setAddress(cell.getContents());
                        break;
                    case 3:
                        contact.setCity(cell.getContents());
                        break;
                    case 4:
                        contact.setContactNo(cell.getContents());
                        break;
                    case 5:
                        contact.setCategory(cell.getContents());
                        break;
                    }

                }
                contacts.add(contact);

            }
            System.out.println("done");
            clist.setContactList(contacts);
            JSONObject jsonlist = new JSONObject(clist);
            File f = new File("/home/vishal/Downloads/database.txt");
            FileOutputStream fos = new FileOutputStream(f, true);
            PrintStream ps = new PrintStream(fos);

            ps.append(jsonlist.toString());

        } catch (BiffException e) {
            e.printStackTrace();
            System.out.println("error");
        }
    }

    public static void main(String[] args) throws IOException {
        ReadExcel test = new ReadExcel();
        test.setInputFile("/home/vishal/Downloads/database.xls");
        test.read();
    }
}

我已经使用jxl.jar进行excel阅读

【讨论】:

  • WorkbookSheetContactList 类是什么?
  • 当我导入 jxl.jar 文件时,我不知道这些类的描述,我从这个库中得到了这些类。如果你愿意,我会给出后记的细节。谢谢
【解决方案2】:

您可以使用 Open CSV 将 CSV 映射到 Java Bean,然后使用 JAXB 将 Java Bean 转换为 JSON 对象。

http://opencsv.sourceforge.net/#javabean-integration

http://jaxb.java.net/guide/Mapping_your_favorite_class.html

【讨论】:

    【解决方案3】:

    这是我的 Java 程序,希望有人觉得它有用。

    格式需要是这样的:

    “SYMBOL,DATE,CLOSE_PRICE,OPEN_PRICE,HIGH_PRICE,LOW_PRICE,VOLUME,ADJ_CLOSE

    AAIT,2015-02-26 00:00:00.000,-35.152,0,35.152,35.12,679,0

    AAL,2015-02-26 00:00:00.000,49.35,50.38,50.38,49.02,7572135,0"

    第一行是列标题。任何地方都没有引号。用逗号而不是分号分隔。你得到了交易。

    /* Summary: Converts a CSV file to a JSON file.*/
    
    //import java.util.*;
    import java.io.*;
    
    import javax.swing.*;
    import javax.swing.filechooser.FileNameExtensionFilter;
    
    public class CSVtoJSON extends JFrame{
        private static final long serialVersionUID = 1L;
        private static File CSVFile;
        private static BufferedReader read;
        private static BufferedWriter write;
    
        public CSVtoJSON(){
            FileNameExtensionFilter filter = new FileNameExtensionFilter("comma separated values", "csv");
            JFileChooser choice = new JFileChooser();
            choice.setFileFilter(filter); //limit the files displayed
    
            int option = choice.showOpenDialog(this);
            if (option == JFileChooser.APPROVE_OPTION) {
                CSVFile = choice.getSelectedFile();
            }
            else{
                JOptionPane.showMessageDialog(this, "Did not select file. Program will exit.", "System Dialog", JOptionPane.PLAIN_MESSAGE);         
                System.exit(1);
            }
        }
    
        public static void main(String args[]){
            CSVtoJSON parse = new CSVtoJSON();
            parse.convert();
    
            System.exit(0);
        }
    
        private void convert(){
            /*Converts a .csv file to .json. Assumes first line is header with columns*/
            try {
                read = new BufferedReader(new FileReader(CSVFile));
    
                String outputName = CSVFile.toString().substring(0, 
                        CSVFile.toString().lastIndexOf(".")) + ".json"; 
                write = new BufferedWriter(new FileWriter(new File(outputName)));
    
                String line;
                String columns[]; //contains column names
                int num_cols;
                String tokens[];
    
                int progress = 0; //check progress
    
                //initialize columns
                line = read.readLine(); 
                columns = line.split(",");
                num_cols = columns.length;
    
    
                write.write("["); //begin file as array
                line = read.readLine();
    
    
                while(true) {
                    tokens = line.split(",");
    
                    if (tokens.length == num_cols){ //if number columns equal to number entries
                        write.write("{");
    
                        for (int k = 0; k < num_cols; ++k){ //for each column 
                            if (tokens[k].matches("^-?[0-9]*\\.?[0-9]*$")){ //if a number
                                write.write("\"" + columns[k] + "\": " + tokens[k]);
                                if (k < num_cols - 1) write.write(", ");                                                }
                            else { //if a string
                                write.write("\"" + columns[k] + "\": \"" + tokens[k] + "\"");
                                if (k < num_cols - 1) write.write(", ");
                            }
                        }
    
                        ++progress; //progress update
                        if (progress % 10000 == 0) System.out.println(progress); //print progress           
    
    
                        if((line = read.readLine()) != null){//if not last line
                            write.write("},");
                            write.newLine();
                        }
                        else{
                            write.write("}]");//if last line
                            write.newLine();
                            break;
                        }
                    }
                    else{
                        //line = read.readLine(); //read next line if wish to continue parsing despite error 
                        JOptionPane.showMessageDialog(this, "ERROR: Formatting error line " + (progress + 2)
                         + ". Failed to parse.", 
                                "System Dialog", JOptionPane.PLAIN_MESSAGE);                    
                        System.exit(-1); //error message
                    }
                }
    
                JOptionPane.showMessageDialog(this, "File converted successfully to "     + outputName, 
                        "System Dialog", JOptionPane.PLAIN_MESSAGE);
    
                write.close();
                read.close();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }       
        }
        }
    

    需要 Swing,但带有一个漂亮的小 GUI,因此那些完全不懂 Java 的人可以在将其打包成可执行的 .jar 后使用它。随意改进它。感谢 StackOverflow 这些年来帮助我。

    【讨论】:

      【解决方案4】:

      @Mouscellaneous 基本上为你回答了这个问题,所以请给他点赞。

      这是我想出的:

      package edu.apollogrp.csvtojson;
      
      import au.com.bytecode.opencsv.bean.CsvToBean;
      import au.com.bytecode.opencsv.bean.HeaderColumnNameMappingStrategy;
      import org.codehaus.jackson.map.ObjectMapper;
      
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.util.List;
      
      public class ConvertCsvToJson {
          public static void main(String[] args) throws IOException, ClassNotFoundException {
              if (args.length > 1) {
                  String pathToCsvFile = args[0];
                  String javaBeanClassName = "edu.apollogrp.csvtojson.bean." + args[1];
                  final File file = new File(pathToCsvFile);
                  if (!file.exists()) {
                      System.out.println("The file you specified does not exist. path=" + pathToCsvFile);
                  }
                  Class<?> type = null;
                  try {
                      type = Class.forName(javaBeanClassName);
                  } catch (ClassNotFoundException e) {
                      System.out.println("The java bean you specified does not exist. className=" + javaBeanClassName);
                  }
      
                  HeaderColumnNameMappingStrategy strat = new HeaderColumnNameMappingStrategy();
                  strat.setType(type);
      
                  CsvToBean csv = new CsvToBean();
                  List list = csv.parse(strat, new InputStreamReader(new FileInputStream(file)));
                  System.out.println(new ObjectMapper().writeValueAsString(list));
              } else {
                  System.out.println("Please specify the path to the csv file.");
              }
          }
      }
      

      我使用 maven 来包含依赖项,但您也可以手动下载它们并将它们包含在您的类路径中。

      <dependency>
          <groupId>net.sf.opencsv</groupId>
          <artifactId>opencsv</artifactId>
          <version>2.0</version>
      </dependency>
      
      <dependency>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-mapper-asl</artifactId>
          <version>1.9.12</version>
      </dependency>
      <dependency>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-core-asl</artifactId>
          <version>1.9.12</version>
      </dependency>
      

      【讨论】:

        【解决方案5】:

        如果您的 CSV 很简单,那么这很容易手工编写 - 但 CSV 可能包含带有引号、缺失值等的令人讨厌的边缘情况。

        • 使用BufferedReader.readLine()加载文件
        • 使用 String.split(",") 从每一行获取值 - 注意,只有在您的值中没有逗号时,这种方法才能正常工作!
        • 使用BufferedWriter将每个值写入输出
          • 带有必要的 JSON 大括号和引号

        您可能想要使用 CSV 库,然后“手动”转换为 JSON

        【讨论】:

          【解决方案6】:

          旧帖子,但我想我会分享我自己的解决方案。它假定在​​值逗号周围使用引号。之后它还会删除所有引用。

          此方法接受 CSV 格式的字符串。因此,它假定您已经将 CSV 文件读取为字符串。确保您在阅读时没有删除 NextLine 字符 ('\n')。

          这种方法绝不是完美的,但它可能是您正在寻找的纯 Java 中的快速单一方法解决方案。

          public String CSVtoJSON(String output) {
          
              String[] lines = output.split("\n");
          
              StringBuilder builder = new StringBuilder();
              builder.append('[');
              String[] headers = new String[0];
          
              //CSV TO JSON
              for (int i = 0; i < lines.length; i++) {
                  String[] values = lines[i].replaceAll("\"", "").split("۞");
          
                  if (i == 0) //INDEX LIST
                  {
                      headers = values;
                  } else {
                      builder.append('{');
                      for (int j = 0; j < values.length && j < headers.length; j++) {
          
                          String jsonvalue = "\"" + headers[j] + "\":\"" + values[j] + "\"";
                          if (j != values.length - 1) { //if not last value of values...
                              jsonvalue += ',';
                          }
                          builder.append(jsonvalue);
                      }
                      builder.append('}');
                      if (i != lines.length - 1) {
                          builder.append(',');
                      }
                  }
              }
              builder.append(']');
              output = builder.toString();
          
              return output;
          }
          

          【讨论】:

            【解决方案7】:

            这是我生成的一个类,用于返回 JSONArray,而不仅仅是打印到文件。

            import com.fasterxml.jackson.databind.ObjectMapper;
            import com.fasterxml.jackson.dataformat.csv.CsvMapper;
            import com.fasterxml.jackson.dataformat.csv.CsvSchema;
            import org.json.simple.JSONArray;
            import org.json.simple.parser.JSONParser;
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;
            
            
            import java.io.File;
            import java.util.List;
            import java.util.Map;
            
            
            public class CsvToJson {
            
            private static final Logger log = LoggerFactory.getLogger(UtilsFormat.class);
            private static CsvToJson instance;
            
            
            public static JSONArray convert(File input) throws Exception {
            
                JSONParser parser = new JSONParser();
                CsvSchema csvSchema = CsvSchema.builder().setUseHeader(true).build();
                CsvMapper csvMapper = new CsvMapper();
            
                // Read data from CSV file
                List<? extends Object> readAll = csvMapper.readerFor(Map.class).with(csvSchema).readValues(input).readAll();
            
                ObjectMapper mapper = new ObjectMapper();
            
                JSONArray jsonObject = (JSONArray) parser.parse(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(readAll));
                System.out.print(jsonObject.toString());
            
                return new JSONArray();
            }
            }
            

            【讨论】:

              【解决方案8】:

              使用 Java 8,编写 JSON 就在眼前。

              您没有指定所需的 JSON API,所以我假设“JSON 对象”是指带有序列化 JSON 对象的字符串。

              我在CSV Cruncher 项目中做了什么:

              1. 使用HSQLDB 加载CSV。这是一个相对较小 (~2 MB) 的库,它实际上实现了一个 SQL 2008 数据库。
              2. 使用 JDBC 查询该数据库。
              3. 构建一个 JDK JSON 对象 (javax.json.JsonObject) 并对其进行序列化。

              这是怎么做的:

              static void convertResultToJson(ResultSet resultSet, Path destFile, boolean printAsArray) 
              {
                          OutputStream outS = new BufferedOutputStream(new FileOutputStream(destFile.toFile()));
                          Writer outW = new OutputStreamWriter(outS, StandardCharsets.UTF_8);
              
                          // javax.json way
                          JsonObjectBuilder builder = Json.createObjectBuilder();
                          // Columns
                          for (int colIndex = 1; colIndex <= metaData.getColumnCount(); colIndex++) {
                              addTheRightTypeToJavaxJsonBuilder(resultSet, colIndex, builder);
                          }
                          JsonObject jsonObject = builder.build();
                          JsonWriter writer = Json.createWriter(outW);
                          writer.writeObject(jsonObject);
              

              整个实现是here。 (最初我编写了自己的 CSV 解析和 JSON 编写,但发现两者都足够复杂,可以使用经过测试的现成库。)

              【讨论】:

                【解决方案9】:

                如果您使用的是 Java 8,则可以执行以下操作。无需库或复杂的逻辑。

                首先,创建一个代表您的新 JSON 对象的 POJO。在我的示例中,它被称为 'YourJSONObject' 并且有一个带有两个字符串的构造函数。

                代码所做的是最初读取文件,然后创建基于字符串的行流。 (一行相当于 CSV 文件中的一行)。

                然后我们将该行传递给 map 函数,该函数用逗号将其拆分,然后创建 YourJSONObject。

                然后将所有这些对象收集到我们传递给 JSONArray 构造函数的列表中。

                您现在有一个 JSONObjects 数组。然后,如果您想查看 this 的文本表示,可以在此对象上调用 toString()。

                        JSONArray objects = new JSONArray(Files.readAllLines(Paths.get("src/main/resources/your_csv_file.csv"))
                            .stream()
                            .map(s -> new YourJSONObject(s.split(",")[0], s.split(",")[1]))
                            .collect(toList()));
                

                【讨论】:

                  猜你喜欢
                  • 2013-03-12
                  • 2013-09-09
                  • 2020-07-23
                  • 1970-01-01
                  • 2012-08-01
                  • 2021-05-05
                  • 2021-12-19
                  • 2015-05-11
                  • 2017-10-25
                  相关资源
                  最近更新 更多