Java: easiest way to read from an Excel-style document? - java

I'm trying to find the best way to read in data from a file similar to an Excel document. It doesn't necessarily need to be an actual excel document, just any file that allows you to enter data in a grid format.
Something where I would be able to do manipulation similar to this:
String val = file.readString(column,row);
float val2 = file.readFloat(column,row);
I'm sorry, I usually try to do more research before I post a question here but I was having a hard time finding much info. A lot of what I saw was 3rd party libraries that read excel files. I'm really hoping if possible I can avoid downloading libraries and hopefully use built in ones.
So I guess my questions in short are:
What's the most appropriate file format for this?
What's the best way to read data from that file?

The first thing that comes to my mind is CSV. CSV files are just regular text files with the .csv filename extension. Data is stored in this format:
cell,anothercell,athirdcell
anotherrow,anothercellonthenewrow,thirdcellofsecondrow
For more specifics, read the CSV specs here.

Option 1
Store your data in a CSV and read with any kind of reader (e.g. BufferedReader). This might be the easiest and fastest solution, if you want to use Excel/LibreOffice for entering data.
Please check out the answers in these threads for various solutions.
String csvfile = path;
BufferedReader br = null;
String line = "";
String cvsSplitby = ";";
try {
br = new BufferedReader(new FileReader(csvfile));
while ((line = br.readLine()) != null) {
String[] i = line.split(cvsSplitby);
// do stuff
}
} catch (all kind of exceptions e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope I didn't miss anything important.
Option 2
Use POI Apache.
Option 3
I've made some decent experience with JXL, but I understand that you don'T want to include too many external libs. (I just saw that it hasn't been updated in while. Consider the other options!)

Related

How to get file content properly from a jpg file?

I'm trying to get content from a jpg file so I can encrypt that content and save it in another file that is later decrypted.
I'm trying to do so by reading the jpg file as if it were a text file with this code:
String aBuffer = "";
try {
File myFile = new File(pathRoot);
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(fIn));
String aDataRow = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow;
}
myReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
But this doesn't give the content the file has, just a short string and weirdly enough it also looks like just reading the file corrupts it.
What could I do so I can achieve the desired behavior?
Image files aren't text - but you're treating the data as textual data. Basically, don't do that. Use the InputStream to load the data into a byte array (or preferably, use Files.readAllBytes(Path) to do it rather more simply).
Keep the binary data as binary data. If you absolutely need a text representation, you'll need to encode it in a way that doesn't lose data - where hex or base64 are the most common ways of doing that.
You mention encryption early in the question: encryption also generally operates on binary data. Any encryption methods which provide text options (e.g. string parameters) are just convenience wrappers which encode the text as binary data and then encrypt it.
and weirdly enough it also looks like just reading the file corrupts it.
I believe you're mistaken about that. Just reading from a file will not change it in any way. Admittedly you're not using try-with-resources statements, so you could end up keeping the file handle open, potentially preventing another process from reading it - but the content of the file itself won't change.

Reading a large compressed file using Apache Commons Compress

I'm trying to read a bz2 file using Apache Commons Compress.
The following code works for a small file.
However for a large file (over 500MB), it ends after reading a few thousands lines without any error.
try {
InputStream fin = new FileInputStream("/data/file.bz2");
BufferedInputStream bis = new BufferedInputStream(fin);
CompressorInputStream input = new CompressorStreamFactory()
.createCompressorInputStream(bis);
BufferedReader br = new BufferedReader(new InputStreamReader(input,
"UTF-8"));
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
Is there another good way to read a large compressed file?
I was having the same problem with a large file, until I noticed that CompressorStreamFactory has a couple of overloaded constructors that take a boolean decompressUntilEOF parameter.
Simply changing to the following may be all that's missing...
CompressorInputStream input = new CompressorStreamFactory(true)
.createCompressorInputStream(bis);
Clearly, whoever wrote this factory seems to think it's better to create new compressor input streams at certain points, with the same underlying buffered input stream so that the new one picks up where the last one left off. They seem to think that's a better default, or preferred way of doing it over allowing one stream to decompress data all the way to the end of the file. I've no doubt they are cleverer than me, and I haven't worked out what trap I'm setting for future me by setting this parameter to true. Maybe someone will tell me in the comments! :-)

Transferring Emojis from Spreadsheet to Java

I would like to transfer data from a google sheet (or any spreadsheet) into java.
How emoji shows up in google sheets: "That picture 😍😍🔥🔥🔥"
How emoji shows up in downloaded TSV: "That picture "ðŸ˜ðŸ˜ðŸ”¥ðŸ”¥ðŸ”¥"
I have trouble understanding how I should be dealing with Emojis:
Is the following correct? I believe the way that emojis behave is that what I see in that first image is the HTML version of the emoji, and that there is an escaped version that looks something like \uD383\u2823
How do I proceed to transfer emojis into java:
What I want to do is be able to count the number of different emojis, so I need to separate them based on their codes.
So it seemed I was freaking out for no reason and should've just gone straight into Java hands first instead of thinking about encodings:
I downloaded my spreadsheet file into TSV
I parsed the TSV file using a regular BufferedReader and used
import org.apache.commons.lang3.StringEscapeUtils;
`BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filename));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
while ((line = reader.readLine()) != null) {
System.out.println(StringEscapeUtils.escapeJava(line));
}
}`
3. output: \u00F0\u0178\u201D\u00A5\u00F0\u0178\u201D\u00A5 for input 🔥🔥

Adding columns to existing csv file using super-csv

I admit I am not a great Java programmer and probably my question is pretty dumb.I need to add new columns in different places to an existing csv file. I'm using the super-csv library.
My input file is something like that
1,2011-5-14 16:30:0.250,A
2,2011-5-14 16:30:21.500,B
3,2011-5-14 16:30:27.000,C
4,2011-5-14 16:30:29.750,B
5,2011-5-14 16:30:34.500,F
AS you can see, i have (or need) no header.
And I need to add a column in column(2) and a column at the end of each row in order to get:
1,1,2011-5-14 16:30:0.250,A,1
2,1,2011-5-14 16:30:21.500,B,1
3,1,2011-5-14 16:30:27.000,C,1
4,1,2011-5-14 16:30:29.750,B,1
5,1,2011-5-14 16:30:34.500,F,1
From the library documentation i got (am i wrong?) that I cannot directly modify the original file, but the best idea is to read it and write it back. I guess using CsvMapReader and CsvMapwriter could be a good choice. But how can I add the columns in between existing ones? I should read each field of the existing column separately, and I tried to find suggestions in the library documentation but i cannot understand how to do it.
You can do it using CsvListReader and CsvListWriter classes. Below you can see simple example how to do it:
CsvListReader reader = new CsvListReader(new FileReader(inputCsv), CsvPreference.STANDARD_PREFERENCE);
CsvListWriter writer = new CsvListWriter(new FileWriter(outputCsv), CsvPreference.STANDARD_PREFERENCE);
List<String> columns;
while ((columns = reader.read()) != null) {
System.out.println("Input: " + columns);
// Add new columns
columns.add(1, "Column_2");
columns.add("Last_column");
System.out.println("Output: " + columns);
writer.write(columns);
}
reader.close();
writer.close();
This is a simple example. You have to catch all exception and close streams in finally block.

Fastest/Cleanest way to load a text file in memory

I know similar questions have been asked before, but I couldn't find one that answers my exact question.
I need a way to read a file as a String with the least code and as simple and as optimal as possible.
I'm not looking for:
final BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null) {
// logic
}
And I know I can write my own helper class that does this.
I'm looking for something more along the lines of:
final String wholeFileAsStr = Something.load(file);
Where Something.load() is super optimized and buffers the file properly while reading it, taking file size into account for instance.
Can anyone recommend something from Guava or Apache maybe that I'm not aware of ?
Thanks in advance.
Perhaps IOUtils.toString , from Commons IOUtils
For a they detailed look at all various methods of reading a single file in a JVM try the following article:
Java tip: How to read files quickly

Categories

Resources