Get data from JSON API and put into CSV in loop - java

I am managed to get the data out of an API and put into a CSV, but I have problems to put the data into the CSV in a loop because right now it always overwrites it in the CSV. And the next problem is that the date does not get shown in the CSV in different fields. In the CSV it looks
like this:
and I want all the data like in my console:
my code right now:
JSONArray jsonarr_1 = (JSONArray) jobj.get("infectedByRegion");
//Get data for Results array
for(int i=0;i<jsonarr_1.size();i++)
{
//Store the JSON objects in an array
//Get the index of the JSON object and print the values as per the index
JSONObject jsonobj_1 = (JSONObject)jsonarr_1.get(i);
//Store the JSON object in JSON array as objects (For level 2 array element i.e Address Components)
String str_data1 = (String) jsonobj_1.get("region");
Long str_data2 = (Long) jsonobj_1.get("infectedCount");
Long str_data3 = (Long) jsonobj_1.get("deceasedCount");
System.out.println(str_data1);
System.out.println("Infizierte: "+str_data2);
System.out.println("Tote: "+str_data3);
System.out.println("\n");
PrintWriter pw = null;
try {
pw = new PrintWriter(new File("C:/Users/stelz/OneDrive/Desktop/Corona Daten/28.04.2020.csv"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
StringBuilder builder = new StringBuilder();
String columnNamesList = "Bundesland,Infizierte,Tote";
// No need give the headers Like: id, Name on builder.append
builder.append(columnNamesList +"\n");
builder.append(str_data1+",");
builder.append(str_data2+",");
builder.append(str_data3);
builder.append('\n');
pw.write(builder.toString());
pw.close();
System.out.println("done!");
}
//Disconnect the HttpURLConnection stream
conn.disconnect();

Your CSV is probably a nice comma delimited file with UTF-8 encoding. The first line in the image from Excel is an evidence that in the file and as text the first line is correctly:
Thüringen,2170,80
But your Excel has probably national defaults for Western Europe, meaning semicolon (';') as CSV separator, and CP1252 (slight variation of the Latin1 charset) for encoding.
How to fix?
Excel is known to have a very poor support for CSV file: read it as text (notepad or notepad++) or use LibreOffice calc which allows to declare the separator and the encoding when reading a CSV file.
If you have to stick to Excel, carefully build your file for your own Excel, use ISO-8859-1 charset and semicolons:
...
PrintWriter pw = null;
try {
pw = new PrintWriter(new File("C:/Users/stelz/OneDrive/Desktop/Corona Daten/28.04.2020.csv"),
"ISO-8859-1");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
StringBuilder builder = new StringBuilder();
String columnNamesList = "Bundesland;Infizierte;Tote";
// No need give the headers Like: id, Name on builder.append
builder.append(columnNamesList +"\n");
builder.append(str_data1+";");
...

It looks like you're trying to create many different CSVs? If this is not what you want and you want all the records in one CSV, then I recommend looping through the array, building a CSV with StringBuilder or some other CSV tool of which there are many, and then creating the file outside of your for loop.

Related

Compare two CSV files on multiple column and create new CSV file in Java

I have two csv files
File 1:
ID,NAME
1,FOO
2,BAR
3,XYZ
File 2:
ID,NAME,DOB
3,XYZ,02/03/1999
4,BAR,01/01/1995
1,FOO,01/01/1996
How can I select rows from CSV File 2 which has columns ID,NAME value matched in File 1 in java language.
Expected Result:
ID,NAME,DOB
3,XYZ,02/03/1999
1,FOO,01/01/1996
Basically you want to perform Vlookup operation .
You can get desired outcome by using Apache POI library. This library provides set of methods to perform Vlookup.
You can refer to the below resources for detailed understanding.
https://poi.apache.org/apidocs/dev/org/apache/poi/ss/formula/functions/Vlookup.html
There are a lot of API's that support functions like comparing .csv files. However, Java also has its own ways to do this.
I'll explain it step by step:
First, you should read the two files into the program. java.io provides some classes with this functionality.
Then, after the content of both files is stored in an appropriate data structure, you can compare them.
You can then simply store the matching lines in another data structure and return them.
Last but not least, you also have to write to a new or already existing file using classes from java.io.
Here is a method to read in files:
public ArrayList<String> readInFile(String absoluteFilePath) {
BufferedReader reader = null;
ArrayList<String> csvContent = new ArrayList<>();
String currentLine;
try {
reader = new BufferedReader(new FileReader(absoluteFilePath));
while((currentLine = reader.readLine()) != null) {
csvContent.add(currentLine);
}
reader.close();
}
catch (Exception e) {
e.printStackTrace();
}
return csvContent;
}
The method uses a BufferedReader to read the file and adds it line by line to the ArrayList
Writing to a .csv file is just as easy as reading from one. You just have to decide whether you want to write to an existing file or to a file that already exists.
Here is a method to write into files:
public void writeToFile(ArrayList<String> csvContent, String absoluteFilePath) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(absoluteFilePath));
for (int i = 0; i < csvContent.size(); i++) {
writer.write(csvContent.get(i) + "\n");
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
This method uses a BufferedWriter to either create a file at the given path or overwrite an existing one and writes the contents of the ArrayList into the file.
Good luck!

How do I read a CSV File with JAVA

I have a probem, and I didnt find any solution yet. Following Problem: I have to read a CSV File which has to look like this:
First Name,Second Name,Age,
Lucas,Miller,17,
Bob,Jefferson,55,
Andrew,Washington,31,
The assignment is to read this CSV File with JAVA and display it like this:
First Name: Lucas
Second Name: Miller
Age: 17
The Attribut Names are not always the same, so it also could be:
Street,Number,Postal Code,ID,
Schoolstreet,93,20000,364236492,
("," has to be replaced with ";")
Also the file Adress is not always the same.
I already have the view etc. I only need the MODEL.
Thanks for your help. :))
I already have a FileChooser class in Controller, which returns an URI.
If your CSV file(s) always contains a Header Line which indicates the Table Column Names then it's just a matter of catching this line and splitting it so as to place those column names into a String Array (or collection, or whatever). The length of this array determines the amount of data expected to be available for each record data line. Once you have the Column Names it's gets relatively easy from there.
How you acquire your CSV file path and it's format type is obviously up to you but here is a general concept how to carry out the task at hand:
public static void readCsvToConsole(String csvFilePath, String csvDelimiter) {
String line; // To hold each valid data line.
String[] columnNames = new String[0]; // To hold Header names.
int dataLineCount = 0; // Count the file lines.
StringBuilder sb = new StringBuilder(); // Used to build the output String.
String ls = System.lineSeparator(); // Use System Line Seperator for output.
// 'Try With Resources' to auto-close the reader
try (BufferedReader br = new BufferedReader(new FileReader(csvFilePath))) {
while ((line = br.readLine()) != null) {
// Skip Blank Lines (if any).
if (line.trim().equals("")) {
continue;
}
dataLineCount++;
// Deal with the Header Line. Line 1 in most CSV files is the Header Line.
if (dataLineCount == 1) {
/* The Regular Expression used in the String#split()
method handles any delimiter/spacing situation.*/
columnNames = line.split("\\s{0,}" + csvDelimiter + "\\s{0,}");
continue; // Don't process this line anymore. Continue loop.
}
// Split the file data line into its respective columnar slot.
String[] lineParts = line.split("\\s{0,}" + csvDelimiter + "\\s{0,}");
/* Iterate through the Column Names and buld a String
using the column names and its' respective data along
with a line break after each Column/Data line. */
for (int i = 0; i < columnNames.length; i++) {
sb.append(columnNames[i]).append(": ").append(lineParts[i]).append(ls);
}
// Display the data record in Console.
System.out.println(sb.toString());
/* Clear the StringBuilder object to prepare for
a new string creation. */
sb.delete(0, sb.capacity());
}
}
// Trap these Exceptions
catch (FileNotFoundException ex) {
System.err.println(ex.getMessage());
}
catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
With this method you can have 1 to thousands of columns, it doesn't matter (not that you would ever have thousands of data columns in any given record but hey....you never know... lol). And to use this method:
// Read CSV To Console Window.
readCsvToConsole("test.csv", ",");
Here is some code that I recently worked on for an interview that might help: https://github.com/KemarCodes/ms3_csv/blob/master/src/main/java/CSVProcess.java
If you always have 3 attributes, I would read the first line of the csv and set values in an object that has three fields: attribute1, attribute2, and attribute3. I would create another class to hold the three values and read all the lines after, creating a new instance each time and reading them in an array list. To print I would just print the values in the attribute class each time alongside each set of values.

Write csv file from byte[]

I am getting a file in byte[] which have comma separated values in quotes, I want to save it as CSV by using OpenCSV. I am using this to save it in CSV format.
Following is my code to convert byte[] to array and then store it in file
byte[] bytes = myByteStream.getFile();
String decoded = new String(bytes, "UTF-8");
//String lines[] = decoded.split("\\r?\\n");
FileOutputStream fos = new FileOutputStream("/home/myPC/Desktop/test.csv");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
CSVWriter writer = new CSVWriter(osw);
String[] row = {decoded};
writer.writeNext(row);
writer.close();
osw.close();
But this above code puts extra quotes around and also merge all lines in one line.
Any help on how to do this properly ?
You can prevent adding quotes to the cell values within the constructor of CSVWriter, for example:
CSVWriter writer = new CSVWriter(osw, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
Regarding the whole byte array persisted as a single row. Are you sure there are newlines within the original file.
If so you might get away by doing the following:
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "ASCII"));
String line;
while ((line = reader.readLine()) != null) {
// Handle the line, ideally in a separate method
}
Got this from splitting a byte array on a particular byte
I think Apache Commons CSV is a better CSV library. From the pasted code it is not clear if you want to somehow change the contents of the file or just duplicate it: in the latter case you don't even need to parse the file as CSV records - just copy it byte-for-byte. In the former case, ie if you need to modify the content of the file, you need something like (Commons CSV used here)
CSVParser parser = CSVFormat.newFormat(',').parse(
new InputStreamReader(new ByteArrayInputStream(bytes), "UTF8"));
CSVPrinter printer = CSVFormat.newFormat(',').print(out);
for (CSVRecord record : parser) {
try {
printer.printRecord(record);
} catch (Exception e) {
throw new RuntimeException("Error at line "
+ parser.getCurrentLineNumber(), e);
}
}
parser.close();
printer.close();
Look at the Javadoc for CSVFormat

New line characters issue in Tweet Content

I am trying to read tweet contents from my DB and write into a .csv file. However, some of the tweets have newline characters, so that is why; the csv file seems weird when I open it.
Could you please help me about how to fix this?
Thanks
//This is reading part
ResultSet rsForSelectTweetContentsQuery = null;
String selectTweetContentsQuery = "SELECT tweetContent FROM filteredtweets WHERE originalTweetId = 4515415454654";
String tweetContent = rsForSelectTweetContentsQuery.getString("tweetContent");
//Thisis writing part
try (BufferedWriter bufferedWriter = new BufferedWriter(csvFileWriter))
{
bufferedWriter.write(tweetId + "," + tweetContent);
bufferedWriter.newLine();
bufferedWriter.close();
}
catch (IOException ex)
{
}
Everybody thinks that CSV files are trivial, but that is actually far from the case. The CSV format has a formal specification, and covers cases like:
Comma itself is a value
A quoted string itself contains quotes
A value has new-lines
Unicode values
etc.
Basically, you don't want to write this yourself, you'll get it wrong. Use this library.

Java read file with strings from different languages

I made a program that reads different text files and combines this into a .csv file. Its a .csv file with translations into English, dutch, french, italian, portuguese and spanish.
Now here is my problem:
In the end i get a nice filled .csv file with all the translations together. I read the files with UTF-8 and all the languages get shown right except for the french one. Some chars are shows as Questionmarks like these: "Mis ? jour" and it should be "Mis à jour".
Here is the method that reads the different files with the different languages and makes objects from them so i can sort them en put them in the right spot in the .csv file
The files are filled like this:
To Airport;A l’aéroport
Today;Aujourd’hui
public static Language getTranslations(String inputFileName) {
Language language = new Language();
FileInputStream fstream;
try {
fstream = new FileInputStream(inputFileName);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream(inputFileName), "UTF-8"));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
String[] values = strLine.split(";");
if(values.length == 2) {
language.putTranslationItem(values[0], values[1]);
}
}
//Close the input stream
in.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
return language;
}
I hope anybody can help out!
Thanks
I am not completely sure about this , but you can try to convert the values[0] and values[1] strings into bytearray
byte[] value_0_utfString = values[0].getBytes("UTF-8") ;
byte[] value_1_utfString = values[1].getBytes("UTF-8") ;
and then convert it back into a string
str_0 = new String(value_0_utfString ,"UTF-8") ;
str_1 = new String(value_1_utfString ,"UTF-8") ;
Not sure if this is the right / optimized way , but since a single line comprises of both english and french , I thought splitting and encoding might help , I haven't tried this myself
Resave the text file by clicking "save as" in any text editor(eg: memopad) and change the encoding type to ANSI instead of UTF-8.

Categories

Resources