I am attempting to put employee details from a CSV file(in the form of FirstName,LastName,DateOfBirth,SSN,Role,Salary,Zip,Phone) with salary being an int. The only problem is, each time I try and implement this code:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class Driver {
//Delimiters used in the CSV file
private static final String COMMA_DELIMITER = ",";
public static void main(String args[])
{
BufferedReader br = null;
try
{
//Reading the csv file
br = new BufferedReader(new FileReader("data.csv"));
//Create List for holding Employee objects
List<Employee> empList = new ArrayList<Employee>();
String line = "";
//Read to skip the header
br.readLine();
//Reading from the second line
while ((line = br.readLine()) != null)
{
String[] employeeDetails = line.split(",");
//Save the employee details in Employee object
Employee emp = new Employee(employeeDetails[0],employeeDetails[1],
employeeDetails[2],
employeeDetails[3],
employeeDetails[4],
Integer.parseInt(employeeDetails[5]),
employeeDetails[6],
employeeDetails[7]);
empList.add(emp);
}
for(int i = 0;i<empList.size();i++){
System.out.println(empList);
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
finally{
try{
br.close();
}
catch(IOException ie){
System.out.println("Error occured while closing the BufferedReader");
ie.printStackTrace();
}
}
}
}
I get a NumbersFormatException error. An employee class has been made with constructors setters and getters.
I just scanned the CSV. There is always a salary which is the root of my confusion.
You need to make sure that: Integer.parseInt(employeeDetails[5])
dosen't fail. So employeeDetails[5] must be a String that can be converted to int.
Like: "5", "123", "567"
Related
I have a record in a CSV file and i am trying to add some extra info (a name) to the same specific record with the following code but it does not work. There is no error shown but the info i am trying to add just does not appear. What am i missing ?
public class AddName {
public static void main(String[] args) {
String filepath="Zoo.csv";
String editTerm="Fish";
String addedName="Ron";
addToRecord(filepath,editTerm,addedName);
}
public static void addToRecord(String filepath,String editTerm,String addedName){
String animal= "";
try{
FileWriter fw=new FileWriter(filepath,true);
BufferedWriter bw=new BufferedWriter(fw);
PrintWriter pw=new PrintWriter(bw);
if (animal.equals(editTerm)){
pw.println(editTerm+","+addedName);
pw.flush();
pw.close();
}
System.out.println("Your Record was saved");
}
catch(Exception e){
System.out.println("Your Record was not saved");
e.printStackTrace();
}
}
You could consider using a CSV library to help you out with parsing CSVs because it is more complicated than it looks, especially when it comes down to quoting.
Here's a quick example using OpenCSV that clones the original CSV file and adds "Ron" as necessary:
public class Csv1 {
public static void main(String[] args) throws IOException, CsvValidationException {
addToRecord("animal.csv", "animal-new.csv", "fish", "Ron");
}
public static void addToRecord(String filepathIn, String filepathOut, String editTerm, String addedName)
throws IOException, CsvValidationException {
try (CSVReader reader = new CSVReader(new FileReader(filepathIn))) {
try (CSVWriter writer = new CSVWriter(new FileWriter(filepathOut))) {
String[] values;
while ((values = reader.readNext()) != null) {
if (values.length > 2 && values[0].equals(editTerm)) {
values[1] = addedName;
}
writer.writeNext(values);
}
}
}
}
}
Given the file:
type,name,age
fish,,10
cat,,12
lion,tony,10
will produce:
"type","name","age"
"fish","Ron","10"
"cat","","12"
"lion","tony","10"
(You can look for answers about outputting quotes in the resulting CSV)
Here the requirement is to add an extra column if the animal name matches. It's equivalent to changing a particular line in a file. Here's a simple approach to achieve the same, (Without using any extra libraries),
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class EditLineInFile {
public static void main(String[] args) {
String animal = "Fish";
Path path = Paths.get("C:\\Zoo.csv");
try {
List<String> allLines = Files.readAllLines(path);
int counter = 0;
for (String line : allLines) {
if (line.equals(animal)) {
line += ",Ron";
allLines.set(counter, line);
}
counter++;
}
Files.write(path, allLines);
} catch (IOException e) {
e.printStackTrace();
}
}
}
You may use this code to replace the file content "Fish" to "Fish, Ron"
public static void addToRecord(String filepath, String editTerm, String addedName) {
try (Stream<String> input = Files.lines(Paths.get(filepath));
PrintWriter output = new PrintWriter("Output.csv", "UTF-8"))
{
input.map(s -> s.replaceAll(editTerm, editTerm + "," + addedName))
.forEachOrdered(output::println);
} catch (IOException e) {
e.printStackTrace();
}
}
I have a java program that will read my CSV file and convert it to XML file, but the issue is that my CSV file has lots of rows and the program can not convert all to XML, so I need to read each 1000 of my csv rows and create a XMl for each of them
Below is my code but I can not read each 1000 rows...
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Scanner;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
public class XMLMainApp {
public static void main(String[] args) throws FileNotFoundException {
UteXmlComunicazione UteXmlComunicazione = new UteXmlComunicazione();
//read the csv file and collect all objects
try {
String inputfile = "sample.csv"; // Source File Name.
double nol = 1000.0; // No. of lines to be split and saved in each output file.
File file = new File(inputfile);
Scanner scanner = new Scanner(file);
int count = 0;
while (scanner.hasNextLine())
{
scanner.nextLine();
count++;
}
System.out.println("Lines in the file: " + count); // Displays no. of lines in the input file.
double temp = (count/nol);
int temp1=(int)temp;
int nof=0;
if(temp1==temp)
{
nof=temp1;
}
else
{
nof=temp1+1;
}
System.out.println("No. of files to be generated :"+nof); // Displays no. of files to be generated.
FileInputStream fstream = new FileInputStream(inputfile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
for (int j=1;j<=nof;j++)
{
while ((line = br.readLine()) != null) { //get every single line individually in csv file
String[] value = line.split(";"); //collect the comma separated values into array
datiCliente datiCliente = new datiCliente();
datiCliente.setcfPiva(value[0]);
... // giving the related Node to each of my fields.
}
UteXmlComunicazione.setdatiFornitoraClienteList(listForCliente);
for (int i=1;i<=nol;i++)
{
//marshaling with java
try {
JAXBContext jaxbContext = JAXBContext.newInstance(UteXmlComunicazione.class);
javax.xml.bind.Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true)
jaxbMarshaller.marshal(UteXmlComunicazione, new File("C:/NewFolder/output"+j+".xml"));
jaxbMarshaller.marshal(UteXmlComunicazione, System.out);
}
catch (JAXBException e) {
e.printStackTrace();
System.out.println("File is not found");
}
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
When I run this code, it creates 180 files (that is correct) but in each of them I have all my rows, not just 1000 rows... and I can not open it.
Can anyone suggest me a solution?
try with following solution, this example is related with your previous question. firstly you should split csv file into multiple csv files including with expected row counts. then, get prepared scv file individually and create xml files
People.java
#XmlRootElement(name="people")
#XmlAccessorType (XmlAccessType.FIELD)
public class People {
#XmlElement(name="person")
private List<Person> listPerson;
public List<Person> getListPerson() {
return listPerson;
}
public void setListPerson(List<Person> listPerson) {
this.listPerson = listPerson;
}
}
Person.java
#XmlRootElement(name="person")
#XmlAccessorType (XmlAccessType.FIELD)
public class Person {
private String id;
private String firstName;
private String lastName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
split csv file into multiple csv files and create xml file separately,
public class Marshaller {
int rowCount;
int fileCount = 1;
PrintWriter writer;
int lineCount;
int index;
String line;
ArrayList<Person> list;
public static void main(String[] args) {
Marshaller marshaller = new Marshaller();
marshaller.readCSV(); //split csv file into multiple csv files
marshaller.readMultipleCSV(); //create XML files using multiple csv files
}
public void readCSV(){
try {
BufferedReader buffeReader = new BufferedReader(new FileReader("inputCSV.csv"));
while ((line = buffeReader.readLine()) != null) { //get every single line individually in csv file
rowCount++;
if(rowCount == 1){
openNewFile();
}
String[] value = line.split(","); //collect the comma separated values into array
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(value[0]+','+value[1]+','+value[2]+'\n'); //append the array values to stringBuilder with comma separation
writer.write(stringBuilder.toString()); //write individual data line into csv file
if(rowCount == 100){
fileCount++;
closeWriter();
}
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void openNewFile(){
try {
writer = new PrintWriter(new File("your_multiple_csv_file_output_path/"+fileCount+".csv")); //create a new csv file
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void closeWriter(){
writer.close(); //close a csv file
rowCount = 0;
}
public void readMultipleCSV(){
ArrayList<File> xmlFileList = new ArrayList();
System.out.println(xmlFileList.size());
xmlFileList.addAll(Arrays.asList(new File("your_multiple_csv_file_output_path").listFiles())); //add all generated csv files into array list
for (int i = 0; i < xmlFileList.size(); i++) {
People people = new People();
ArrayList<Person> list = new ArrayList();
try {
BufferedReader br = new BufferedReader(new FileReader(xmlFileList.get(i).toString())); //get csv file separately
while ((line = br.readLine()) != null) { //get every single line individually in csv file
String[] value = line.split(","); //collect the comma separated values into array
Person person = new Person();
person.setId(value[0]); //first element of an array is id
person.setFirstName(value[1]); //second element of an array is firstName
person.setLastName(value[2]); //third element of an array is lastName
list.add(person); //add person object into the list
}
} catch (IOException e) {
e.printStackTrace();
}
people.setListPerson(list);
prepareXML(people, i);
}
}
public void prepareXML(People people, int csvFileNo){
//marshaling with java
try {
JAXBContext jaxbContext = JAXBContext.newInstance(People.class);
javax.xml.bind.Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(people, new File("your_xml_file_output_path/output "+(csvFileNo+1)+".xml"));
jaxbMarshaller.marshal(people, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
inputCSV.csv (without columns' names)
1,yong,mook kim
2, Alez, Aunritod
3,yong,mook kim
.
.
.
I put in my csv some results Like this:
ID COUNTRY
0009 FR
0006 FR
The problem is that when I open my file.CSV,I read under ID the values 9 and 6 and not 0009 and 0006. How is it possibile and How I can avoid this problem? Anyone can help me?
(Given that the question is tagged with Java.)
If you have a CSV as mentioned, which is tab separated:
ID COUNTRY
0009 FR
0006 FR
Suppose it is located at: src/com/stackoverflow/myfile.csv
You can read it as below:
package com.stackoverflow;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CsvReader {
public static final String CSVFILE = "src/com/stackoverflow/myfile.csv";
public static void main(String[] args) {
BufferedReader br = null;
String line = "";
String cvsSplitBy = "\\t+"; // use tab as separator
try {
br = new BufferedReader(new FileReader(CSVFILE));
while ((line = br.readLine()) != null) {
String[] info = line.split(cvsSplitBy);
StringBuilder details = new StringBuilder();
details.append("ID = ");
details.append(info[0]);
details.append(", Country = ");
details.append(info[1]);
System.out.println(details.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
And the output would be:
ID = ID, Country = COUNTRY
ID = 0009, Country = FR
ID = 0006, Country = FR
Note: it is 0009 and 0006
UPDATED (Just Java 8 way to read the CSV file):
package com.stackoverflow;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class CsvReader {
public static final String CSVFILE = "src/com/stackoverflow/myfile.csv";
public static void main(String[] args) {
String cvsSplitBy = "\\t+"; // use tab as separator
try (Stream<String> stream = Files.lines(Paths.get(CSVFILE))) {
stream.forEach(line -> {
String[] info = line.split(cvsSplitBy);
StringBuilder details = new StringBuilder();
details.append("ID = ");
details.append(info[0]);
details.append(", Country = ");
details.append(info[1]);
System.out.println(details.toString());
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
You could escape the value as a string
ID COUNTRY
"0009" FR
"0006" FR
I believe your problem has nothing to do with Java, I'd assume you're using a tab processor (Excel, Calc, ...). When opening the file, you have to explicitly set the column type to text, otherwise it will "guess" it's a number and clean the leading zeros.
Updated Code. This program should take the CSV file and separate it into TSV files by school,but I am not getting it to work. I am getting it to create the files correctly, but only one has any data in it...
public class Student implements Comparable<Student>{
public int id = 0;
public String name = "";
public String school = "";
public Student(int id, String name, String school){
this.id = id;
this.name = name;
this.school = school;
}
public String toString(){
return id+"\t"+name+"\t"+school;
}
#Override
public int compareTo(Student o) {
return this.school.compareTo(o.school);
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
public class ReadCSV {
public static String CSV_FILE_PATH = "/Users/eringray/Desktop/csvtotab/input.csv";
public static void main(String[] args){
try {
BufferedReader br = new BufferedReader(new FileReader(CSV_FILE_PATH));
BufferedWriter bw = new BufferedWriter(new FileWriter(CSV_FILE_PATH + ".tsv"));
ArrayList<Student> list = new ArrayList<Student>();
String line = "";
while((line = br.readLine()) != null) {
String[] values = line.split(",");
if(values.length == 3) {
String idAsString = values[0];
String name = values[1];
String school = values[2];
int id = Integer.parseInt(idAsString);
Student s = new Student(id, name, school);
list.add(s);
}
}
Collections.sort(list);
String currentSchool = "";
for(int i = 0; i < list.size(); i++){
Student stu = list.get(i);
if(currentSchool != stu.school){
currentSchool = stu.school;
bw = new BufferedWriter(new FileWriter(CSV_FILE_PATH + stu.school + ".tsv"));
}
String lineText = stu.toString();
bw.write(lineText);
bw.newLine();
}
br.close();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The first thing, you have to do is reading the input file.
I think, you need to read it line by line (depends on file structure).
https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html
Next step is to seperate the data and sort it by school (if i understood your question well).
For this you have to split the data and create a class to store the information:
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
public Class Student{
public String name = "";
....
public Student(String name, String school, ...){}
}
When you have created a Student object for each student in the list, you have to sort the students by school:
You could implement compareable and use Collection.sort().
https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
Last thing is to print the output, for this you have to override the toString method of the student class:
public String toString(){
return this.id+"\t"+this.name+"\t"+this.school;
}
and iterate throug the list of your students and call the toString method:
System.out.println(students.get(i).toString());
EDIT:
If you need the output in a file and not in the console, just use a fileoutputStream and a bufferedwriter to print the output of the toString method in a file.
Ok, I'm really confused by some code I wrote. It's a DataSetter (didn't know a better name for it...), and has methods to change the data in my data file (data.txt). This data has the following format: #key=value (eg. #version=1.0). Now, I tried to run this line of code:
new DataSetter().setValue("version", "1.1");
It just clears the file. That's pretty much all it does. Now, I think it clears the file because it makes a new File, which is completely empty but has the same name. Here's my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
/**
* This class contains methods to set specific data in the data.txt file. <br>
* The data is rewritten every time a new value is set.
*
* #author Casper van Battum
*
*/
public class DataSetter {
private static final File DATA_FILE = new File("resources/data.txt");
private static final String lineFormat = "#%s=%s";
private FileOutputStream out;
private DataReader reader = new DataReader();
private HashMap<String, String> dataMap = reader.getDataMap();
private Scanner scanner;
public DataSetter() {
try {
out = new FileOutputStream(DATA_FILE, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void setValue(String key, String newValue) {
openDataFile();
String oldLine = String.format(lineFormat, key, dataMap.get(key));
dataMap.put(key, newValue);
String newLine = String.format(lineFormat, key, newValue);
try {
replace(oldLine, newLine);
} catch (IOException e) {
e.printStackTrace();
}
closeDataFile();
}
private void replace(String oldLine, String newLine) throws IOException {
ArrayList<String> tmpData = new ArrayList<String>();
while (scanner.hasNextLine()) {
String currentLine = scanner.nextLine();
tmpData.add((currentLine == oldLine) ? newLine : currentLine);
}
out.write(new String().getBytes());
String sep = System.getProperty("line.separator");
StringBuffer sb = new StringBuffer();
for (String string : tmpData) {
sb.append(string + sep);
}
FileWriter writer = new FileWriter(DATA_FILE);
String outString = sb.toString();
writer.write(outString);
writer.close();
}
private void openDataFile() {
try {
scanner = new Scanner(DATA_FILE);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
private void closeDataFile() {
scanner.close();
}
}
So after running the setValue() method, I just have an empty file...
Im really out of idea's on how to solve this...
You are truncating your data file with the
new FileOutputStream(DATA_FILE, false)
so no nothing is written when you go to output your the elements in the tmpData ArrayList read from Scanner.
ArrayList<String> tmpData = new ArrayList<String>();
while (scanner.hasNextLine()) {
String currentLine = scanner.nextLine(); // never gets called
...
}
The typical strategy for updating a text file is to create a temporary file with old file's contents (File#renameTo), write the data to file, then delete the temporary file after closing any open streams to the file being read.