【问题标题】:Java-TestNG : Read an excel file, assert and write back to the excel file through TestNG & Apache POIJava-TestNG : 读取一个 excel 文件,通过 TestNG & Apache POI 断言并写回 excel 文件
【发布时间】:2017-04-17 16:08:39
【问题描述】:

我正在使用 Apache POI 使用 Selenium Java 和 TestNG 开发 POC。我有一个 Excel 表,其中 A 列包含 url,B 列包含状态(是或否)是否使用相应的 url 读取/执行。我想将执行状态通过/失败保存在 C 列中。

我的 Excel 表“TestData.xlsx”

我的调用文件“read_write_excel.java”如下:

package Read_Write_Excel;
import org.testng.annotations.Test;
import libraries.read_excel_data;
public class read_write_excel 
{

    String path = "C:\\SeleniumUtilities\\excelData\\TestData.xlsx";
    @Test
    public void read_excel() throws Exception
    {
        read_excel_data excel = new read_excel_data(path);
        excel.read_data(0);
    }
}

通过“read_excel_data.java”读取excel表格如下:

package libraries;

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

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class read_excel_data 
{

    XSSFWorkbook workbook;
    XSSFSheet sheet;
    String location;
    int SheetNo;
    write_excel_data write_excel;
    public read_excel_data(String excelPath)
        {
            location = excelPath;
            try {
                File src = new File(excelPath);
                FileInputStream fis = new FileInputStream(src);
                workbook = new XSSFWorkbook(fis);
                write_excel = new write_excel_data(location);

            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }


    public void read_data(int sheetNumber) throws Exception
    {
        SheetNo = sheetNumber;
        sheet = workbook.getSheetAt(sheetNumber);
        int rows = sheet.getLastRowNum();
        System.out.println("Total number of Rows to read : "+(rows+1));
        for(int i=0;i<=rows;i++)
        {
            XSSFRow now_row = sheet.getRow(i);
            if(now_row.getCell(1).getStringCellValue().equalsIgnoreCase("yes"))
            {
                String data = now_row.getCell(0).getStringCellValue();
                System.out.println("Data from Row "+i+" is: "+data);
                String status = assertion.asserting(data);
                System.out.println("Status is : "+status);
                write_excel.write_data(SheetNo,i,status);
            }
        }

        workbook.close();
    }

}

断言在“assertion.java”中完成,例如:

package libraries;
public class assertion 
{

    public static String asserting(String url)
    {
        String result;
        if(url.contains("com"))
            {
                result = "Pass";
                System.out.println("Result is : "+result);
                return result;
            }
        else
            {
                result = "Fail";
                System.out.println("Result is : "+result);
                return result;
            }

    }
}

通过“write_excel_data.java”写回excel文件,如:

package libraries;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class write_excel_data 
{

    File des;
    XSSFSheet sheet;
    XSSFWorkbook wb;
    public write_excel_data(String location)
    {
        try {
            des = new File(location);
            FileInputStream fis = new FileInputStream(des);
            wb = new XSSFWorkbook(fis);


        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public void write_data(int sheetNo,int i, String status) throws Exception
    {
        sheet = wb.getSheetAt(sheetNo);
        int rows = sheet.getLastRowNum();
        System.out.println("Total number of Rows to write : "+(rows+1));
        sheet.getRow(i).createCell(2).setCellValue(status);
        FileOutputStream fos = new FileOutputStream(des);
        wb.write(fos);
        wb.close();
    }
}

我面临的问题是:

  1. 有时我会遇到 NullPointerException

  2. 有时 Excel 工作表会损坏并且根本不写入。

请告诉我:

  1. 我的方法正确吗?

  2. 有什么改进建议吗?

  3. 如果我在这里犯了任何错误。


更新-1:

最新的堆栈跟踪:

[TestNG] Running:
  C:\Users\DEDLY\AppData\Local\Temp\testng-eclipse--1619303069\testng-customsuite.xml

Total number of Rows to read : 3
Data from Row 0 is: a.com
Result is : Pass
Status is : Pass
Total number of Rows to write : 3
Data from Row 1 is: b.com
Result is : Pass
Status is : Pass
Total number of Rows to write : 3
[Utils] Attempting to create C:\Users\DEDLY\workspace\SeleniumJavaTestNG\test-output\Default suite\Default test.xml
[Utils]   Directory C:\Users\DEDLY\workspace\SeleniumJavaTestNG\test-output\Default suite exists: true
FAILED: read_excel
org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Rule M2.4 exception : this error should NEVER happen, if so please send a mail to the developers team, thanks !
    at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.getContentType(ContentTypeManager.java:342)
    at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.removeContentType(ContentTypeManager.java:255)
    at org.apache.poi.openxml4j.opc.OPCPackage.removePart(OPCPackage.java:943)
    at org.apache.poi.openxml4j.opc.PackagePart.getOutputStream(PackagePart.java:522)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.commit(XSSFWorkbook.java:1546)
    at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:332)
    at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:195)
    at libraries.write_excel_data.write_data(write_excel_data.java:38)
    at libraries.read_excel_data.read_data(read_excel_data.java:51)
    at Read_Write_Excel.read_write_excel.read_excel(read_write_excel.java:15)
    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:100)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:646)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:811)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1137)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
    at org.testng.TestRunner.privateRun(TestRunner.java:753)
    at org.testng.TestRunner.run(TestRunner.java:607)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:368)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:363)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:321)
    at org.testng.SuiteRunner.run(SuiteRunner.java:270)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1284)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1209)
    at org.testng.TestNG.runSuites(TestNG.java:1124)
    at org.testng.TestNG.run(TestNG.java:1096)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81)


===============================================
    Default test
    Tests run: 1, Failures: 1, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 1, Failures: 1, Skips: 0
===============================================

更新 - 2:

当我尝试手动打开“TestData.xlsx”时,我收到以下错误

【问题讨论】:

  • 请从您的空指针异常中粘贴堆栈跟踪。此外,当您没有问题 1 或 2 时,它是否按预期正常工作?
  • @BillK 谢谢,我已经用最新的堆栈跟踪更新了我的问题。请你看看好吗?
  • 在 wb.close() 之前;尝试使用 wb.flush();
  • @AnandGaneshSS 谢谢。但是当我尝试添加该行时,Eclipse IDE 显示错误为The method flush() is undefined for the type XSSFWorkbook
  • 文件同时打开两次。您应该先尝试在write_excel_data 中传递XSSFWorkbook

标签: java apache-poi testng


【解决方案1】:

只看你的堆栈跟踪,它看起来可能与单元格类型有关(最上面的调用是“removeContentType”和“getContentType”。我认为这意味着它试图将一个字符串放入一个 int单元格,或者可能是一个不存在的单元格。

尝试在 C 列的三个单元格中的每一个中放置文本作为开始。如果可行,您可以查看 API 以查看是否可以设置该单元格的类型。

如果这不起作用,您可以尝试将初始电子表格(来自 Excel)保存为旧类型。有时 Poi 不能与最新的 excel 版本一起使用。

我不知道你在哪里设置“des”,你是否省略了一些代码或者你忘了设置它?无论如何,尝试不同的源/目标,不要覆盖(我不知道你是不是)。

另外,既然您提出了建议:

  1. Java 希望所有包(在世界上)都具有唯一的名称,因此不要将“库”用作包,而应考虑使用 com.mycompany.project.libraries 或类似名称。
  2. 所有变量都应该是私有的。就那样做吧。唯一的例外是“public final static”常量,它们应该只引用不可变对象(int、String、...)
  3. 类名应该是(例如)WriteExcelData 而不是 write_excel_data。虽然这只是一种模式,但它在社区中非常一致地使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-06
    • 2015-06-30
    • 1970-01-01
    • 2014-12-05
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多