I have a list and want to write the data into .csv file.
This is an example how my list looks like:
Each element contains the values from a database table. I deleted the information here. For example List[0] contains id = 1, name = Test, date = 02.02.2016 etc.
This is my code so far, but I have no Idea how to continue.
List<String> lines = Arrays.asList("ColumnHeader", "ColumnHeader", " ColumnHeader","ColumnHeader","ColumnHeader");
Path file = Paths.get(test.csv");
Files.write(file, lines, Charset.forName("Windows-1252"));
Take a look at OpenCSV. This library contains tools for writing List and array objects to csv files, and even database result sets can be written directly to a file.
CSVWriter writer = new CSVWriter(new FileWriter("yourfile.csv"), '#');
java.sql.ResultSet myResultSet = ....
writer.writeAll(myResultSet, includeHeaders);
writer.close();
Related
I am new to Java. I was successfully able to read my CSV file from my local file location and was able to identify which column needed to be deleted for my requirements. However, I was not able to delete the required column and write the file into my local folder. Is there a way to resolve this issue? I have used the following code:
CSVReader reader = new CSVReader(new FileReader(fileName));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
System.out.println(nextLine[15]);
}
All I would like to do is to remove the column having index 15 and write the file as a CSV file in my local folder.
I'm assuming you're using the OpenCSV library.
In order to make your code work, you have to fix 2 issues:
You need a writer to write your modified CSV to. OpenCSV provides a CSVWriter class for this purpose.
You need to convert your line (which is currently a String array) into a list to be able to remove an element, then convert it back into an array to match what the CSVWriter.writeNext method expects.
Here's some code that does this:
CSVReader reader = new CSVReader(new FileReader(fileName));
CSVWriter writer = new CSVWriter(new FileWriter(outFileName));
String[] origLine;
while ((origLine = reader.readNext()) != null) {
List<String> lineList = new ArrayList<>(Arrays.asList(origLine));
lineList.remove(15);
String[] newLine = lineList.toArray(new String[lineList.size()]);
writer.writeNext(newLine, true);
}
writer.close();
reader.close();
Some additional remarks:
The code probably needs a bit more error handling etc if it's to be used in a production capacity.
List indices in Java start at 0, so remove[15] actually removes the 16th column from the file.
The code writes its output to a separate file. Trying to use the same file name for input and output will not work.
I need to write in a specific cell in a .csv file with org.apache.commons.csv library whitout iterate and copy all lines.
I tried this:
Reader reader = Files.newBufferedReader(Paths.get(Properties.dataFilePath));
CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
List<CSVRecord> records = csvParser.getRecords();
records.get(rowNumber)[columnIndex] = value;
However it is not allowed.
Edit 1
My IDE mentioned : The type of the expression must be an array type but it resolved to CSVRecord
have you tried it with
value = records.get(rowNumber).get(columnIndex);?
Have a look here, it may help you: https://commons.apache.org/proper/commons-csv/apidocs/org/apache/commons/csv/CSVRecord.html
val csv_writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest+"whatever"+".csv")))
for (x <-storeTimestamp ) {
csv_writer.write(x + "\n")
}
csv_writer.close()
Is there any other ways to write 2 lists of string to a csv file?
For now in my code, I only wrote 1 list of string to the csv file. How to add a new column from another list?
Is it OK to use Bufferedwriter?
If I understand your question, you have some CSV data and you want to add a new column of data to the end of each line before writing it to a file.
Here's how I might go about it.
// some pretend data
val origCSV = Seq("a,b,c", "d,e,f", "x,y,z")
val newCLMN = Seq("4X", "2W", "9A")
// put them together
val allData = origCSV.zip(newCLMN).map{case (a,b) => s"$a,$b\n"}
Note: zip will only zip the two collections together until it runs out of one or the other. It there's data left in the larger collection then it is ignored. If that's not desirable then you might try zipAll.
On to the file writing.
import java.io.{File, FileWriter}
import util.Try
val writer = Try(new FileWriter(new File("filename.csv")))
writer.map{w => w.write(allData.mkString); w}
.recoverWith{case e => e.printStackTrace(); writer}
.map(_.close())
And the result is...
>> cat filename.csv
a,b,c,4X
d,e,f,2W
x,y,z,9A
>>
I am reading two different csv files and populating data into two different objects. I am splitting each line of csv file based on regex(regex is different for two csv files) and populating the object using each data of that array which is obtained by splitting each line using regex as shown below:
public static <T> List<T> readCsv(String filePath, String type) {
List<T> list = new ArrayList<T>();
try {
File file = new File(filePath);
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)
list = bufferedReader.lines().skip(1).map(line -> {
T obj = null;
String[] data = null;
if (type.equalsIgnoreCase("Student")) {
data = line.split(",");
ABC abc = new ABC();
abc.setName(data[0]);
abc.setRollNo(data[1]);
abc.setMobileNo(data[2]);
obj = (T)abc;
} else if (type.equalsIgnoreCase("Employee")) {
data = line.split("\\|");
XYZ xyz = new XYZ();s
xyz.setName(Integer.parseInt(data[0]));
xyz.setCity(data[1]);
xyz.setEmployer(data[2]);
xyz.setDesignation(data[3]);
obj = (T)xyz;
}
return obj;
}).collect(Collectors.toList());} catch(Exception e) {
}}
csv files are as below:
i. csv file to populate ABC object:
Name,rollNo,mobileNo
Test1,1000,8888888888
Test2,1001,9999999990
ii. csv file to populate XYZ object
Name|City|Employer|Designation
Test1|City1|Emp1|SSE
Test2|City2|Emp2|
The issue is there can be a missing data for any of the above columns in the csv file as shown in the second csv file. In that case, I will get ArrayIndexOutOfBounds exception.
Can anyone let me know what is the best way to populate the object using the data of the string array?
Thanks in advance.
In addition to the other mistakes you made and that were pointed out to you in the comments your actual problem is caused by line.split("\\|") calling line.split("\\|", 0) which discards the trailing empty String. You need to call it with line.split("\\|", -1) instead and it will work.
The problem appears to be that one or more of the last values on any given CSV line may be empty. In that case, you run into the fact that String.split(String) suppresses trailing empty strings.
Supposing that you can rely on all the fields in fact being present, even if empty, you can simply use the two-arg form of split():
data = line.split(",", -1);
You can find details in that method's API docs.
If you cannot be confident that the fields will be present at all, then you can force them to be by adding delimiters to the end of the input string:
data = (line + ",,").split(",", -1);
Since you only use the first values few values, any extra trailing values introduced by the extra delimiters would be ignored.
What am i doing? I am exporting my sqlite database into a csv -- atleast i try to
I've done this both manually and with "OpenCSV".
With both methods I get very strange results. They just seem not well formatted. Neither the columns (which are usually seperated by ',' ? ) nor special characters (which are said to be handled within opencsv) look like they should. code:
CSVWriter writer = new CSVWriter(new FileWriter(file),'\n',',');
String[] items = new String[11];
c.moveToFirst();
while(!c.isAfterLast()){
items[0] = c.getString(c.getColumnIndex(BaseColumns._ID));
items[1] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_QRCODE));
items[2] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_NAME));
items[3] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_AMOUNT));
items[4] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_UNIT));
items[5] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_PPU));
items[6] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_TOTAL));
items[7] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_COMMENT));
items[8] = c.getString(c.getColumnIndex(DepotTableMetaData.ITEM_SHOPPING));
items[9] = c.getString(c.getColumnIndex(DepotTableMetaData.CREATED_DATE));
items[10] = c.getString(c.getColumnIndex(DepotTableMetaData.MODIFIED_DATE));
c.moveToNext();
writer.writeNext(items);
}
writer.close();
and it all gives this as a result:
I've also done it through FileWriter and StringBuffer but it seems to give exactly the same results...I'd love if you could help me ;)
I have looked through stackoverflow but couldn't find any matching question ;/
edit: yes i know that I use the "old, deprecated" cursor, but that's not the question here. Thanks.
edit2: SOLVED !
you have to assign some common encoding !
CSVWriter writer = new CSVWriter(new OutputStreamWriter(new FileOutputStream(destination+"/output.csv"),"UTF-8"));
did the job perfectly!
You use an OpenCSV Writer, which takes a row of the CSV file as an array of Strings, and generates the separators between columns and rows automatically, but instead of letting OpenCSV do it for you, you do it explicitely by appending all the values of a row in a single String. So obviously, OpenCSV takes your unique value and considers it contains a single column, where commas and newlines must be encoded.
You should call writer.writeNext() with an array of Strings, each String in the array being a single cell from the table. The writer will generate the commas and the newlines for you.