简体   繁体   English

在Java中将CSV文件转换为JSON对象

[英]Converting an CSV file to a JSON object in Java

Is there an open source java library to convert a CSV (or XLS) file to a JSON object? 是否有一个开源java库将CSV(或XLS)文件转换为JSON对象?

I tried using json.cdl , but somehow it does not seem to work for large CSV strings. 我尝试使用json.cdl ,但不知何故它似乎不适用于大型CSV字符串。

I'm trying to find something like http://www.cparker15.com/code/utilities/csv-to-json/ , but written in Java. 我正在尝试找到类似http://www.cparker15.com/code/utilities/csv-to-json/的内容 ,但是用Java编写。

You can use Open CSV to map CSV to a Java Bean, and then use JAXB to convert the Java Bean into a JSON object. 您可以使用Open CSV将CSV映射到Java Bean,然后使用JAXB将Java Bean转换为JSON对象。

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

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

Here is my Java program and hope somebody finds it useful. 这是我的Java程序,希望有人发现它很有用。

Format needs to be like this: 格式需要像这样:

"SYMBOL,DATE,CLOSE_PRICE,OPEN_PRICE,HIGH_PRICE,LOW_PRICE,VOLUME,ADJ_CLOSE “SYMBOL,DATE,CLOSE_PRICE,OPEN_PRICE,HIGH_PRICE,LOW_PRICE,体积,ADJ_CLOSE

AAIT,2015-02-26 00:00:00.000,-35.152,0,35.152,35.12,679,0 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" AAL,2015-02-26 00:00:00.000,49.35,50.38,50.38,49.02,7572135,0“

First line is the column headers. 第一行是列标题。 No quotation marks anywhere. 任何地方都没有引号。 Separate with commas and not semicolons. 用逗号分隔而不用分号。 You get the deal. 你得到了这笔交易。

/* 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();
        }       
    }
    }

Requires Swing but comes with a nifty little GUI so those who know absolutely no Java can use it once packaged into an executable .jar. 需要Swing但是带有一个漂亮的小GUI,所以那些完全不知道Java的人可以在打包成可执行文件后使用它.jar。 Feel free to improve upon it. 随意改进它。 Thank you StackOverflow for helping me out all these years. 感谢StackOverflow这些年帮助我。

@Mouscellaneous basically answered this for you so please give him the credit. @Mouscellaneous基本上都是为你解答的,所以请给他信用。

Here is what I came up with: 这是我想出的:

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.");
        }
    }
}

I used maven to include the dependencies, but you could also download them manually and include them in your classpath. 我使用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>

If your CSV is simple, then this is easy to write by hand - but CSV can include nasty edge cases with quoting, missing values, etc. 如果您的CSV很简单,那么这很容易手工编写 - 但CSV可以包含带引号,缺失值等的令人讨厌的边缘情况。

  • load the file using BufferedReader.readLine() 使用BufferedReader.readLine()加载文件
  • use String.split(",") to get the value from each line - NB this approach will only work correctly if your values don't have commas in! 使用String.split(",")从每一行获取值 - 注意,如果您的值没有逗号,这种方法只能正常工作!
  • write each value to the output using BufferedWriter 使用BufferedWriter将每个值写入输出
    • with the necessary JSON braces and quoting 使用必要的JSON括号和引号

You might want to use a CSV library, then convert to JSON 'by hand' 您可能想要使用CSV库,然后手动转换为JSON

I have used excel file in this code.you can use csv. 我在这段代码中使用了excel文件。你可以使用csv。 i have wrote this class for particular Excel/csv format which is known to me. 我已经为我所知的特定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();
    }
}

i have used jxl.jar for excel reading 我使用jxl.jar进行excel阅读

With Java 8, writing JSON is at hand. 使用Java 8,编写JSON即将到来。

You didn't specify what JSON API you want, so I assume by "JSON object" you mean a string with a serialized JSON object. 你没有指定你想要的JSON API,所以我假设“JSON对象”是指带有序列化JSON对象的字符串。

What I did in the CSV Cruncher project: 我在CSV Cruncher项目中做了什么:

  1. Load the CSV using HSQLDB . 使用HSQLDB加载CSV。 That's a relatively small (~2 MB) library, which actually implements a SQL 2008 database. 这是一个相对较小(约2 MB)的库,它实际上实现了SQL 2008数据库。
  2. Query that database using JDBC. 使用JDBC查询该数据库。
  3. Build a JDK JSON object ( javax.json.JsonObject ) and serialize it. 构建JDK JSON对象( javax.json.JsonObject )并对其进行序列化。

Here's how to do it: 这是怎么做的:

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);

The whole impl is here . 整个impl就在这里 (Originally I wrote my own CSV parsing and JSON writing, but figured out both are complicated enough to reach for a tested out-of-the-shelf library.) (最初我写了我自己的CSV解析和JSON写作,但想到两者都很复杂,足以达到一个经过测试的现成库。)

If you're using Java 8, you can do something like this. 如果您使用的是Java 8,则可以执行此类操作。 No Libraries or complicated logic required. 不需要库或复杂的逻辑。

Firstly, create a POJO representing your new JSON object. 首先,创建一个表示新JSON对象的POJO。 In my example it's called 'YourJSONObject' and has a constructor taking two strings. 在我的例子中,它被称为'YourJSONObject'并且有一个带两个字符串的构造函数。

What the code does is initially reads the file, then creates a stream of String based lines. 代码所做的最初是读取文件,然后创建基于String的行的流。 ( a line is equivalent to a line in your CSV file). (一行相当于CSV文件中的一行)。

We then pass the line in to the map function which splits it on a comma and then creates the YourJSONObject. 然后,我们将该行传递给map函数,该函数将其拆分为逗号,然后创建YourJSONObject。

All of these objects are then collected to a list which we pass in to the JSONArray constructor. 然后将所有这些对象收集到我们传递给JSONArray构造函数的列表中。

You now have an Array of JSONObjects. 您现在拥有一个JSONObjects数组。 You can then call toString() on this object if you want to see the text representation of 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()));

Here is a class I generated to return JSONArray, not just to print to a file. 这是我为返回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();
}
}

Old post but I thought I'd share my own solution. 旧帖但我以为我会分享自己的解决方案。 It assumes quotations are used around an in-value comma. 它假定引号用于值内逗号。 It also removes all quotations afterwards. 它之后也会删除所有报价。

This method accepts a String in CSV format. 此方法接受CSV格式的字符串。 So it assumes you've already read the CSV file to a string. 因此,它假设您已经将CSV文件读取为字符串。 Make sure you didn't remove the NextLine characters ('\\n') while reading. 确保在阅读时没有删除NextLine字符('\\ n')。

This method in no way perfect, but it might be the quick one-method solution in pure java you are looking for. 这种方法绝不是完美的,但它可能是您正在寻找的纯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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM