How to save from JTable to CSV or Excel? - java

Is there a way to save JTable data to excel? I would like to save the data that I input from the program, from the table and then to a CSV file.
I would like to have it so that there is a button that will then save the inputted data from the GUI into the table and then to the CSV file.

This may help you:-
Method to write to a csv file.
public static void exportToCSV(JTable table,
String path) {
try {
TableModel model = table.getModel();
FileWriter csv = new FileWriter(new File(path));
for (int i = 0; i < model.getColumnCount(); i++) {
csv.write(model.getColumnName(i) + ",");
}
csv.write("\n");
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
csv.write(model.getValueAt(i, j).toString() + ",");
}
csv.write("\n");
}
csv.close();
} catch (IOException e) {
System.out.println("Error "+e);
}
}
For reading and showing it to a JTable you can use OpenCSV.
CSVReader reader = new CSVReader(new FileReader("file.csv"));
List list = reader.readAll();
JTable table = new JTable(list.toArray());

There is no 'magic function' of a JTable that I know of that will do this. JTable is a UI component, and what you're asking for is a data function, not a user interface function. And it doesn't have much to do with eclipse, which is just the IDE one uses to write the code.
I think what you may be looking for is the model on which the JTable is based. The first solution that occurs to me is to alter that model code to have a method that will write out the data in the format you want; then a(nother) button on your UI would invoke this method on the model to write out the data when the user chooses. There are likely other ways you might get this done, but that seems the most straightforward and easiest.

You can try this code:
public static boolean convertToCSV(JTable table,
String path) {
try {
TableModel model = table.getModel();
FileWriter csv = new FileWriter(new File(path));
for (int i = 0; i < model.getColumnCount(); i++) {
csv.write(model.getColumnName(i) + ",");
}
csv.write("\n");
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
csv.write(model.getValueAt(i, j).toString() + ",");
}
csv.write("\n");
}
csv.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}

Related

Escape comma when using csv writer

My application writes the data from Jtable to a csv file.
I use the below function:
public static boolean exportToCSV(JTable RnRFetchTable,String pathToExportTo) {
try {
DateFormat writeDateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
Date writeDate = new Date();
TableModel model = RnRFetchTable2.getModel();
FileWriter csv = new FileWriter(new File("C:/Users/Desktop/TableExport" + writeDateFormat.format(writeDate) + ".csv"));
for (int i = 0; i < model1.getColumnCount(); i++) {
csv.write(model1.getColumnName(i) + ",");
}
csv.write("\n");
for (int i = 0; i < model1.getRowCount(); i++) {
for (int j = 0; j < model1.getColumnCount(); j++) {
csv.write(model1.getValueAt(i, j).toString() + ",");
}
csv.write("\n");
}
csv.close();
JOptionPane.showMessageDialog(null,"Export Successful!");
return true;
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null,"Error! Excel cannot be exported!");
}
return false;
}
This code works fine when one of the columns don't have the comma, but when it does, the delimiting happens wherever the "," comes. How to write the csv by escaping comma?
You can surround your text with double quotes:
csv.write("\"" + model1.getValueAt(i, j).toString() + "\",");

How to dynamically rename csv exports, when using csv writer in Java

I have the below code which exports a Jtable as Excel csv export.
I tried appending the file (boolean true), but the append happens within the same file itself.
public static boolean exportToCSV(JTable table,String pathToExportTo) {
try {
TableModel model = table.getModel();
FileWriter csv = new FileWriter(new File("C:/Users/user/Desktop/test.csv"));
for (int i = 0; i < model.getColumnCount(); i++) {
csv.write(model.getColumnName(i) + ",");
}
csv.write("\n");
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
csv.write(model.getValueAt(i, j).toString() + ",");
}
csv.write("\n");
}
csv.close();
JOptionPane.showMessageDialog(null,"Export Successful!");
return true;
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null,"Error! Excel cannot be exported!");
}
return false;
This is working fine, but this overwrites the existing file. I would want this to be exported as a different file and probably rename as text(1).csv
You could use a method to compute report output file:
File resolveFileName(){
String directory ="C:/Users/user/Desktop/";
File res = new File(directory + "test.csv");
if(!res.exists()){
return res;
}
int filesInDirectoryCount = (new File(directory)).listFiles().length;
String fileName = "test_"+filesInDirectoryCount+".csv";
return new File(directory+fileName);
}
Usage:
FileWriter csv = new FileWriter(resolveFileName);
This will add a numer to the file name, based on numer of files in this directory. So it should help with this problem.

upload large .xlsx file in gui java

i have a large excel file containing 600.000 rows , i used XSSFWorkbook to upload the excel file at a Jtable in my GUI but it takes about 15 minutes to be done in eclipse and once i export my project to a jar file i can't do it even in the 15 minutes . Any help please ?
Here is the method , that i found in internet to upload my excel file .
void fillData(File file) {
int index = -1;
XSSFWorkbook workbook = null;
try {
try {
String f = file.getPath();
File file1 = new File(f);
OPCPackage opcPackage = OPCPackage.open(file1);
workbook = new XSSFWorkbook(opcPackage);
} catch (IOException ex) {
Logger.getLogger(ProjectApp3.class.getName()).log(Level.SEVERE, null, ex);
}
String[] strs = new String[workbook.getNumberOfSheets()];
//get all sheet names from selected workbook
for (int i = 0; i < strs.length; i++) {
strs[i] = workbook.getSheetName(i);
}
JFrame frame = new JFrame("Input Dialog");
//select sheet
String selectedsheet = (String) JOptionPane.showInputDialog(
frame, "Which worksheet you want to import ?", "Select Worksheet",
JOptionPane.QUESTION_MESSAGE, null, strs, strs[0]);
if (selectedsheet != null) {
for (int i = 0; i < strs.length; i++) {
if (workbook.getSheetName(i).equalsIgnoreCase(selectedsheet))
index = i;
}
XSSFSheet sheet = workbook.getSheetAt(index);
XSSFRow row = sheet.getRow(0);
//import headers data
headers.clear();
for (int i = 0; i < row.getLastCellNum(); i++) {
XSSFCell cell1 = row.getCell(i);
headers.add(cell1.toString());
}
//import data
data1.clear();
for (int j = 1; j < sheet.getLastRowNum() + 1; j++) {
Vector d = new Vector();
row = sheet.getRow(j);
int noofrows = row.getLastCellNum();
for (int i = 0; i < noofrows; i++) { //To handle empty excel cells
XSSFCell cell = row.getCell(i,
org.apache.poi.ss.usermodel.Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
d.add(cell.toString());
}
d.add("\n");
data1.add(d);
}
} else {
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
I think the basic problem is that you're trying to give. your Jtable all the data at startup. This is going to be deeply problematic. You may want to write a custom subclass from AbstractTableModel. See the docs for Jtable that includes this:
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
JTable table = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(table);
You can implement those three methods based on the info that POI gives you. But do lazy loading of the data, most especially for getValueAt(). Keep the spreadsheet file open and grab the data only when the user scrolls to view it.

Writing to a text file using Java gets cut short

I have a program reading from a text file (currently 653 lines long) all separated by a comma. But when I go to save the file to a new location, it only saves 490 lines. It also seems that the last line in the newly created text file is cut in half. Any ideas on what might be the problem?
Here is the code that I used to open and sort the data in the list:
try {
scanner = new Scanner(file);
// Put the database into an array and
// Make sure each String array is 13 in length
while (scanner.hasNext()) {
line = scanner.nextLine();
word = line.split(",");
if (word.length < 13) {
String[] word2 = {"","","","","","","","","","","","",""};
for (int i = 0; i < word.length; i++) {
word2[i] = word[i];
}
dataBaseArray.add(word2);
}
else {
dataBaseArray.add(word);
}
}
}
catch (FileNotFoundException exc) {
JOptionPane.showMessageDialog(this, "File cannot be found.", "error finding file", JOptionPane.ERROR_MESSAGE);
}
// Splitting the database into vacant numbers/dead lines/vacant cubicles
for (int i = 0; i < dataBaseArray.size(); i++) {
if (dataBaseArray.get(i)[8].equals("VACANT")) {
vacantNums.add(dataBaseArray.get(i));
}
else if (dataBaseArray.get(i)[4].equals("DEAD")) {
deadLines.add(dataBaseArray.get(i));
}
else if (dataBaseArray.get(i)[6].equals("") && dataBaseArray.get(i)[7].equals("")) {
vacantCubs.add(dataBaseArray.get(i));
}
else if (dataBaseArray.get(i)[7].equals("")) {
people.add(dataBaseArray.get(i));
}
else {
people.add(dataBaseArray.get(i));
}
}
// Resetting the DB Array to put the values back in it
dataBaseArray = new ArrayList<>();
// Ordering the arrays I want them to appear in the list
// Orering the people to appear in alphabetical order
Collections.sort(people, new Comparator<String[]>() {
#Override
public int compare(String[] strings, String[] otherStrings) {
return strings[7].compareTo(otherStrings[7]);
}
});
// Put the people in the DB Array
for (int i = 0; i < people.size(); i++) {
dataBaseArray.add(people.get(i));
}
// Put the vacant numbers in the AB Array
for (int i = 0; i < vacantNums.size(); i++) {
dataBaseArray.add(vacantNums.get(i));
}
// Put the vacant cubicles in the AB Array
for (int i = 0; i < vacantCubs.size(); i++) {
dataBaseArray.add(vacantCubs.get(i));
}
// Put the dead lines in the AB Array
for (int i = 0; i < deadLines.size(); i++) {
dataBaseArray.add(deadLines.get(i));
}
list = new String[dataBaseArray.size()];
// Add the DB Array to the list
for (int i = 0; i < list.length; i++) {
if (dataBaseArray.get(i)[8].equals("VACANT")) {
list[i] = "VACANT";
}
else if (dataBaseArray.get(i)[4].equals("DEAD")) {
list[i] = "DEAD";
}
else if (dataBaseArray.get(i)[6].equals("") && dataBaseArray.get(i)[7].equals("")) {
list[i] = "Vacant Cubicle";
}
else if (dataBaseArray.get(i)[7].equals("")) {
list[i] = dataBaseArray.get(i)[6];
}
else {
list[i] = dataBaseArray.get(i)[7] + ", " + dataBaseArray.get(i)[6];
}
}
// Populate the list
lstAdvance.setListData(list);
Here is what I used to save the file:
try {
saveFile = new FileWriter("Save Location");
String newLine = System.getProperty("line.separator");
for (int i = 0; i < dataBaseArray.size(); i++) {
for (int j = 0; j < dataBaseArray.get(i).length; j++) {
saveFile.append(dataBaseArray.get(i)[j] + ",");
}
saveFile.append(newLine);
}
}
catch (IOException exc) {
JOptionPane.showMessageDialog(this,"error", "error", JOptionPane.ERROR_MESSAGE);
}
Writing to a file is buffered. You have to close() or flush() your writer (saveFile) at the end of writing.
Even better: you should do close() on your writer in the finally block.
Try it using the FileWriter and BufferedWriter....
File f = new File("Your_Path");
FileWriter fw = new FileWriter(f);
BufferedWriter bw = new BufferedWriter(fw);
And yes..its very important to do bw.close() (Closing the Buffer)
See this question : Java FileWriter with append mode
The problem is that your FileWriter object needs to be "append mode" . Then, you append to the file with the "write" method rather than the "append" method. Use a finally catch clause to call "close" . You don't need to flush ( I dont think).

How to export JFreeChart Data to csv file

I have used Java Swing along with JFreeChart for plotting graphs in the tool we are designing. Now i want to export the graph data to CSV file.(say upon right click on graph it should give an option of exporting to CSV and upon selecting it, a csv file should be created in some random location and save the graph data into it).
The important point here is how to save data into CSV from graph. I need to use Java Swing and JFreeChart for achieving this.
Try using this:
JFreeChart chart;
// ... initialization of chart
XYDataSet dataSet = chart.getXYPlot().getDataset();
Then use of the dataSet is pretty straightforward.
Here is a concrete example:
private void storeDataSet(JFreeChart chart, String filename) {
java.util.List<String> csv = new ArrayList<>();
if (chart.getPlot() instanceof XYPlot) {
Dataset dataset = chart.getXYPlot().getDataset();
XYDataset xyDataset = (XYDataset) dataset;
int seriesCount = xyDataset.getSeriesCount();
for (int i = 0; i < seriesCount; i++) {
int itemCount = xyDataset.getItemCount(i);
for (int j = 0; j < itemCount; j++) {
Comparable key = xyDataset.getSeriesKey(i);
Number x = xyDataset.getX(i, j);
Number y = xyDataset.getY(i, j);
csv.add(String.format("%s, %s, %s", key, x, y));
}
}
} else if (chart.getPlot() instanceof CategoryPlot) {
Dataset dataset = chart.getCategoryPlot().getDataset();
CategoryDataset categoryDataset = (CategoryDataset) dataset;
int columnCount = categoryDataset.getColumnCount();
int rowCount = categoryDataset.getRowCount();
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
Comparable key = categoryDataset.getRowKey(i);
Number n = categoryDataset.getValue(i, j);
csv.add(String.format("%s, %s", key, n));
}
}
} else {
throw new IllegalStateException("Unknown dataset");
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename + ".csv"));) {
for (String line : csv) {
writer.append(line);
writer.newLine();
}
} catch (IOException e) {
throw new IllegalStateException("Cannot write dataset", e);
}
}

Categories