使用Apache POI写入excel。 FileNotFoundException :(无法对打开了用户映射部分的文件执行请求的操作)

时间:2018-04-12 16:49:26

标签: java excel selenium apache-poi

任何人都可以帮助照亮这个吗?我正在尝试编写一个数据数组,以便从selenium测试脚本中擅长到下一个空行。我的代码适用于生成第一次执行excel,正确写入数据,然后第二次执行(在同一应用程序运行中),后续执行会抛出以下内容:

java.io.FileNotFoundException: TestResultData2.xls (The requested operation cannot be performed on a file with a user-mapped section open)

经过几个小时的尝试和搜索,我发现这可能与Windows问题有关(请参阅:https://bz.apache.org/bugzilla/show_bug.cgi?id=58480),但我不确定我是否遗漏了一些补救措施..大多数其他搜索显示这可能是由此引起的从没有关闭FileOutputStream但它是如此我在那里感到困惑。 请参阅以下exportDataToExcel方法。注意我尝试了很多不同的方法,但这是我最近/最经过测试的尝试。

public static void exportDataToExcel(String fileName, String tabName, String[][] data) throws FileNotFoundException, IOException, EncryptedDocumentException, InvalidFormatException, Exception
  {
    //Create new workbook and tab
    Workbook wb;
    File newFile = new File(fileName);
    Sheet sheet = null;

    if (newFile.exists()) { 
           // Load existing
           wb = WorkbookFactory.create(newFile);
    }else {
           if (newFile.getName().endsWith(".xls")) {
               wb = new HSSFWorkbook();
           }else {
               throw new IllegalArgumentException("Unknown file type. Please use .xls");
           }
    }
    FileOutputStream fileOut = new FileOutputStream(newFile);

    // Check if the workbook is empty or not
    if (wb.getNumberOfSheets() != 0) {
        for (int i = 0; i < wb.getNumberOfSheets(); i++) {
           if (wb.getSheetName(i).equals(tabName)) {
               sheet = wb.getSheet(tabName);
           }else sheet = wb.createSheet(tabName);
        }
    }else {
        // Create new sheet to the workbook if empty
        sheet = wb.createSheet(tabName);
    }

      //Create 2D Cell Array
      Row[] row = new Row[data.length];
      Cell[][] cell = new Cell[row.length][];
      //Define and Assign Cell Data from Given
      for(int i = 0; i < row.length; i ++)
      {           
          row[i] = sheet.createRow(i);  
          cell[i] = new Cell[data[i].length];

          for(int j = 0; j < cell[i].length; j ++)
          {
              cell[i][j] = row[i].createCell(j);
              cell[i][j].setCellValue(data[i][j]);
          }
      }

      //Export Data
      wb.write(fileOut);
      fileOut.close();
      wb.close();
      System.out.println("File exported successfully");

  }

我通过以下方式调用方法:

String data[][]= {{cpAppFN, cpAppLN, cpAppDOB, cpAppSSN}};
exportDataToExcel("TestResultData2.xls", "Results2", data);

下面的Stacktrace,供参考。

Test_ConsumerPortal Line 210 is FileOutputStream fileOut = new FileOutputStream(newFile);Line 142 is exportDataToExcel("TestResultData2.xls", "Results2", data);在测试中。

java.io.FileNotFoundException: TestResultData2.xls (The requested operation cannot be performed on a file with a user-mapped section open)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at tests.Test_ConsumerPortal.exportDataToExcel(Test_ConsumerPortal.java:210)
at tests.Test_ConsumerPortal.Execution(Test_ConsumerPortal.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)


java.io.FileNotFoundException: TestResultData2.xls (The requested operation cannot be performed on a file with a user-mapped section open)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at tests.Test_ConsumerPortal.exportDataToExcel(Test_ConsumerPortal.java:210)
at tests.Test_ConsumerPortal.Execution(Test_ConsumerPortal.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)

如果还有其他信息,请告诉我。

1 个答案:

答案 0 :(得分:2)

调用wb = WorkbookFactory.create(newFile)时,会在内部创建FileInputStream。在不关闭FileInputStream的情况下,您正在FileOutputStream呼叫FileOutputStream fileOut = new FileOutputStream(newFile);

当您创建工作簿时,WorkbookFactory.create(newFile)`不起作用,因此第一次尝试通过。在随后的尝试中,所提到的代码路径被命中并且代码中断。

如果文件存在,解决方法是打开FileInputStream,然后将其传递到create()。完成更新Excel工作表中的值后,关闭FileInputStream并打开FileOutputStream以写入新数据。

下面的代码应该按原样运行。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class ExcelDataUpdater {

    public static void exportDataToExcel(String fileName, String tabName, String[][] data)
            throws FileNotFoundException, IOException, EncryptedDocumentException, InvalidFormatException, Exception {
        // Create new workbook and tab
        FileInputStream inputStream = null;
        Workbook wb;
        Sheet sheet = null;

        // Check the file extension
        if (!fileName.endsWith(".xls")) {
            throw new IllegalArgumentException("Unknown file type. Please use .xls");
        }

        File newFile = new File(fileName);

        // If file not exists we create a new workbook
        if (!newFile.exists()) {
            wb = new HSSFWorkbook();
        } else {
            // If file exists, we open an input stream channel to it
            inputStream = new FileInputStream(newFile);
            // Provide the input stream to WorkbookFactory
            wb = WorkbookFactory.create(inputStream);
        }

        // Check if the workbook is empty or not
        boolean isSheetFound = false;
        for (int i = 0; i < wb.getNumberOfSheets(); i++) {
            if (wb.getSheetName(i).equals(tabName)) {
                sheet = wb.getSheet(tabName);
                isSheetFound = true;
            }
        }
        if (!isSheetFound) {
            sheet = wb.createSheet(tabName);
        }

        // Create 2D Cell Array
        Row[] row = new Row[data.length];
        Cell[][] cell = new Cell[row.length][];
        // Define and Assign Cell Data from Given
        for (int i = 0; i < row.length; i++) {
            row[i] = sheet.createRow(i);
            cell[i] = new Cell[data[i].length];

            for (int j = 0; j < cell[i].length; j++) {
                cell[i][j] = row[i].createCell(j);
                cell[i][j].setCellValue(data[i][j]);
            }
        }

        // If file already exists, we had opened an input stream.
        // We will close this here
        if (inputStream != null)
            inputStream.close();

        FileOutputStream outputStream = new FileOutputStream(newFile);

        // Export Data
        wb.write(outputStream);
        outputStream.close();
        wb.close();
        System.out.println("File exported successfully");
    }

    public static void main(String[] args)
            throws InvalidFormatException, EncryptedDocumentException, FileNotFoundException, IOException, Exception {
        String data1[][] = { { "A", "B", "C", "D" } };
        ExcelDataUpdater.exportDataToExcel("TestResultData2.xls", "Results1", data1);

        String data2[][] = { { "X", "Y", "Z", "W" } };
        ExcelDataUpdater.exportDataToExcel("TestResultData2.xls", "Results2", data2);
    }
}

我还优化了用于检查工作表是否存在以及创建工作表的代码。