I am working on a java application that reads a file template.ods, and fills it in with an array of Objects using JopenDocument.
Based on the JopenDocument documentation, I should get the TableModel from the Sheet, and then use the method setValueAt(value, rowIndex, columnIndex) to modify it, but once I do that, an IndexOutofBoundsException is triggered, Here is my method:
Main.class
public File generateODSFileWithTemplate(String fileName, Object[][] rows, File template) throws FileNotFoundException { final Sheet sheet = SpreadSheet.createFromFile(template).getSheet(0); sheet.getSpreadSheet().getTableModel("data").setValueAt("Hello from Main", 3, 1); File outFile = new File(fileName); sheet.getSpreadSheet().saveAs(outFile); return outFile; }
template.ods
If I add a value in the first row using :
sheet.getSpreadSheet().getTableModel("data").setValueAt("Hello from Main", 0, 0);
It works, and the column value gets updated.
I am wondering what I am doing wrong to get this exception ?
Is there a way to pass the array direcly to the TableModel just like DefaultTableModel to insert the data.
I am using OpenOffice to create the template.ods
Advertisement
Answer
When working with spread sheet documents, I always remember that you can scroll the GUI to infinity… Haha. Do you see where I am going with this? I mean that there must be a way of determining the size (in rows and columns) of the document, because we cannot store an infinitely large one, with no values. There is also no point in it, so we have to specify the size of it. To do this, call ensureColumnCount
and/or ensureRowCount
as appropriate, prior setting the values of the cell at row index 3, because there is simply no row allocated in the model of a file which contains only 1 row. Or, at least, that’s the reason I can understand we get an IndexOutOfBoundsException
.
The following code, demonstrates the problem and runs as expected:
import javax.swing.table.DefaultTableModel; import org.jopendocument.dom.spreadsheet.Sheet; import org.jopendocument.dom.spreadsheet.SpreadSheet; public class Main { public static void main(final String[] args) { final SpreadSheet spread = SpreadSheet.createEmpty(new DefaultTableModel()); final Sheet sheet = spread.getFirstSheet(); try { sheet.setValueAt("Will fail", 4, 4); } catch (final RuntimeException x) { System.out.println(x.toString() + " thrown. Fixing..."); sheet.ensureColumnCount(5); sheet.ensureRowCount(5); sheet.setValueAt("Hello world", 4, 4); //Will not throw. } } }
Sheet
is a Table<SpreadSheet>
so it provides you with those (required) methods.