-1

I have written a method that successfully exports data from an array to an Excel file. However, I would like Java to automatically open the freshly created Excel file when Apache POI is done writing it.

My code looks like this:

public void exportData(Object[][] data, String[] columnNames) {
    HSSFWorkbook wb = new HSSFWorkbook();

    // Export logic here...

    FileOutputStream fileOut = new FileOutputStream(new File(myFilePath));
    wb.write(fileOut); // Write the Excel file
    fileOut.close(); // Close it
    openFile(); // Open it with Excel
}

public void openFile() { // Excel file opening method
    try {
        Runtime.getRuntime().exec("cmd.exe /c start " + new File(myFilePath));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

It behaves as follows:

  • When I call exportData() during runtime, the Excel file is written as it should be, but is not automatically opened.
  • If I "manually" call openFile() again afterwards (through a JButton ActionEvent, for example), it works.
  • If I start my application in NetBeans' debug mode and proceed step by step, it works without needing to manually call openFile() afterwards.

My guess is that something is being done in the background here, and that it takes some time, while my program goes on; therefore, I think my Runtime.exec() may happen before the file is ready to be opened.

Do you think it is the case? Is there a better way to do it? If not, how can I delay Runtime.exec() accordingly?

Aeronth
  • 804
  • 1
  • 6
  • 16
  • Maybe `.flush()` your output stream? Also, you should close in a finally block. – fge Jul 09 '13 at 09:42
  • 3
    Join us in the 3rd millennium and use `ProcessBuilder` instead of `exec`. As general advice: 1) Read (and implement) *all* the recommendations of [When Runtime.exec() won't](http://www.javaworld.com/jw-12-2000/jw-1229-traps.html). Then ignore that it refers to `exec` and build the `Process` using a `ProcessBuilder`. Also break a `String arg` into `String[] args` to account for arguments which themselves contain spaces. 2) Change code of the form `catch (Exception e) { ..` to `catch (Exception e) { e.printStackTrace(); // very informative! ..` – Andrew Thompson Jul 09 '13 at 09:42
  • Thank you. As for the stack trace, I merely removed that part of the code when pasting it here. There is no exception raised anyway. – Aeronth Jul 09 '13 at 09:48
  • 1
    Does `Desktop.getDesktop().open(new File(myFilePath));` work better ? – ARRG Jul 09 '13 at 14:30
  • @ARRG: Yes! Actually, I realized the problem still existed with `ProcessBuilder`. Yours always work. – Aeronth Jul 10 '13 at 07:50

1 Answers1

2

I don't know what is the exact problem that prevents your command from working. But in general, when you want to open a file, it makes sense to use java.awt.Desktop instead of spawning a process to do so.

So in your case

Runtime.getRuntime().exec("cmd.exe /c start " + new File(myFilePath));

Becomes

Desktop.getDesktop().open(new File(myFilePath));

AWT takes care of ensuring everything goes smoothly, and you get better cross-platform support this way.

ARRG
  • 2,476
  • 17
  • 28