excel 使用 jxl 写入大数据时文件损坏
excel file is geting corrupted when writing large data using jxl
我正在尝试使用 groovy 进行一些自动化操作。我正在获取另一个请求的响应数据,并使用 jxl jar 将请求和输出都存储在 excel 中。但如果我这样做,我的 excel 文件就会损坏。但是当我做单个请求响应时它工作正常。所以我想知道 jxl 是否存在内存问题?如果是,如何解决?
这是我的脚本:
import jxl.*
import jxl.write.*
import groovy.sql.Sql
//Datasheet read define start
def projectLocation="E:/"
def dataFileLocation=projectLocation+"zip.xls"
def workbook = Workbook.getWorkbook(new File(dataFileLocation))
def readSheet = workbook.getSheet(0)
def rowCount = readSheet.getRows()
def colCount = readSheet.getColumns()
def myTestCase = context.testCase
//db config
def url = 'jdbc:hsqldb:hsql://localhost/'
def user = 'sa'
def password = ''
def driver = 'org.hsqldb.jdbcDriver'
def sql = Sql.newInstance(url, user, password, driver)
propTestStep = myTestCase.getTestStepByName("Properties");
//Datasheet read end
//Content Write define start
WorkbookSettings s = new WorkbookSettings();
s.setUseTemporaryFileDuringWrite(true);
// s.setInitialFileSize(100000000)
WritableWorkbook workbook1 = Workbook.createWorkbook(new File(projectLocation+"output1.xls"),s)
WritableSheet writeSheet = workbook1.createSheet("new", 0)
//
//WritableWorkbook workbook2 = Workbook.createWorkbook(new File(projectLocation+"output2.xls"))
//WritableSheet writeSheet1 = workbook2.createSheet("newOutput", 0)
def project = testRunner.testCase.testSuite.project
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
//Content Write define end
for(int i = 1;i < rowCount; i++)
{
for(int j = 0;j < colCount; j++)
{
val= readSheet.getCell(j,i).getContents()
// log.info "before storing in zip val="+ val
// propTestStep.setPropertyValue("zip",val)
def req=groovyUtils.getXmlHolder( "GetInfoByZIP#Request" )
req["//web:USZip"] = val
req.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByZIP'] )
// log.info "before sending to db val="+val
sql.eachRow('select state,city from zip where zip=?',[val]){ row ->
st= row.state
ct= row.city
}
//log.info st+" "+ct
def res=groovyUtils.getXmlHolder( "GetInfoByZIP#Response" )
def state = res.getNodeValues( "//STATE" )
def city=res.getNodeValues("//CITY")
def ct1=city[0]
log.info ct +" " + ct1
if(ct1.equalsIgnoreCase(ct)){
// log.info "city equals"
}
else{
// log.info "not eq"
}
def req1=groovyUtils.getXmlHolder( "GetInfoByState#Request" )
req1["//web:USState"]=state[0]
req1.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByState'] )
def respo1= testRunner.testCase.testSteps["GetInfoByState"].testRequest.response.contentAsString
Label labelReq = new Label(j,i,context.testCase.getTestStepByName("GetInfoByZIP").getProperty("request").value)
Label labelReq1 = new Label(j+2,i,context.testCase.getTestStepByName("GetInfoByState").getProperty("request").value)
def response = testRunner.testCase.testSteps["GetInfoByZIP"].testRequest.response.contentAsString
Label labelResp = new Label(j+1,i,response);
Label labelResp1 = new Label(j+3,i,respo1);
writeSheet.addCell(labelReq)
writeSheet.addCell(labelResp);
log.info respo1
writeSheet.addCell(labelReq1)
writeSheet.addCell(labelResp1);
}
}
workbook1.write()
workbook1.close()
很可能是您无意中覆盖了某些内容。我不知道那是什么。但是,一个好的起点是使用更简洁的代码。所以我建议使用 Frosted Sheets(由 Apache POI 支持)而不是 JXL。它使工作簿 MUCH much 的工作变得更加容易。
我写这个库是因为我厌倦了看到一些有史以来最糟糕的代码,而且我知道它可以做得更多......Groovy-ly。
import com.emmanuelrosa.frostedsheets.*
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import groovy.sql.Sql
def projectLocation="E:/"
def dataFileLocation="${projectLocation}zip.xls"
def workbook = new FrostedWorkbook(new HSSFWorkbook(new FileInputStream(dataFileLocation)))
def rowCount = readSheet.getRows()
def colCount = readSheet.getColumns()
def myTestCase = context.testCase
def url = 'jdbc:hsqldb:hsql://localhost/'
def user = 'sa'
def password = ''
def driver = 'org.hsqldb.jdbcDriver'
def sql = Sql.newInstance(url, user, password, driver)
propTestStep = myTestCase.getTestStepByName("Properties");
def workbook1 = FrostedWorkbook.createXLS()
def writeSheet = workbook1['new']
def project = testRunner.testCase.testSuite.project
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
/*
* cellIterator() returns a special Iterator which traverses
* through the cells by row, then column; top-down, left-right.
* It eliminates the need for nested loops.
*/
workbook[0].cellIterator().each { cell ->
req["//web:USZip"] = cell.cellValue
def req=groovyUtils.getXmlHolder( "GetInfoByZIP#Request" )
req.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByZIP'] )
sql.eachRow('select state,city from zip where zip=?',[val]) { row ->
st= row.state
ct= row.city
}
def res=groovyUtils.getXmlHolder( "GetInfoByZIP#Response" )
def state = res.getNodeValues( "//STATE" )
def city=res.getNodeValues("//CITY")
def ct1=city[0]
log.info ct +" " + ct1
if(ct1.equalsIgnoreCase(ct)) {
// log.info "city equals"
}
else{
// log.info "not eq"
}
def req1=groovyUtils.getXmlHolder( "GetInfoByState#Request" )
req1["//web:USState"]=state[0]
req1.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByState'] )
writeSheet[cell.rowIndex + 1].with {
def stateInfo = testRunner.testCase.testSteps["GetInfoByState"].testRequest.response.contentAsString
def zipValue = context.testCase.getTestStepByName("GetInfoByZIP").getProperty("request").value
def stateValue = context.testCase.getTestStepByName("GetInfoByState").getProperty("request").value
def zipInfo = testRunner.testCase.testSteps["GetInfoByZIP"].testRequest.response.contentAsString
// Add the columns to the row
append [zipValue, zipInfo, stateValue, stateInfo]
}
}
new FileOutputStream("${projectLocation}output1.xls").withStream { stream ->
workbook1.write(stream)
}
我认为您的响应数据超出了 excel 的单元格限制。您可以通过在 word 中复制粘贴响应来检查该内容,检查那里有多少个字符。 Excel 一行可以包含 32,767 个字符。如果超过这个值,它可能会损坏。
我正在尝试使用 groovy 进行一些自动化操作。我正在获取另一个请求的响应数据,并使用 jxl jar 将请求和输出都存储在 excel 中。但如果我这样做,我的 excel 文件就会损坏。但是当我做单个请求响应时它工作正常。所以我想知道 jxl 是否存在内存问题?如果是,如何解决?
这是我的脚本:
import jxl.*
import jxl.write.*
import groovy.sql.Sql
//Datasheet read define start
def projectLocation="E:/"
def dataFileLocation=projectLocation+"zip.xls"
def workbook = Workbook.getWorkbook(new File(dataFileLocation))
def readSheet = workbook.getSheet(0)
def rowCount = readSheet.getRows()
def colCount = readSheet.getColumns()
def myTestCase = context.testCase
//db config
def url = 'jdbc:hsqldb:hsql://localhost/'
def user = 'sa'
def password = ''
def driver = 'org.hsqldb.jdbcDriver'
def sql = Sql.newInstance(url, user, password, driver)
propTestStep = myTestCase.getTestStepByName("Properties");
//Datasheet read end
//Content Write define start
WorkbookSettings s = new WorkbookSettings();
s.setUseTemporaryFileDuringWrite(true);
// s.setInitialFileSize(100000000)
WritableWorkbook workbook1 = Workbook.createWorkbook(new File(projectLocation+"output1.xls"),s)
WritableSheet writeSheet = workbook1.createSheet("new", 0)
//
//WritableWorkbook workbook2 = Workbook.createWorkbook(new File(projectLocation+"output2.xls"))
//WritableSheet writeSheet1 = workbook2.createSheet("newOutput", 0)
def project = testRunner.testCase.testSuite.project
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
//Content Write define end
for(int i = 1;i < rowCount; i++)
{
for(int j = 0;j < colCount; j++)
{
val= readSheet.getCell(j,i).getContents()
// log.info "before storing in zip val="+ val
// propTestStep.setPropertyValue("zip",val)
def req=groovyUtils.getXmlHolder( "GetInfoByZIP#Request" )
req["//web:USZip"] = val
req.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByZIP'] )
// log.info "before sending to db val="+val
sql.eachRow('select state,city from zip where zip=?',[val]){ row ->
st= row.state
ct= row.city
}
//log.info st+" "+ct
def res=groovyUtils.getXmlHolder( "GetInfoByZIP#Response" )
def state = res.getNodeValues( "//STATE" )
def city=res.getNodeValues("//CITY")
def ct1=city[0]
log.info ct +" " + ct1
if(ct1.equalsIgnoreCase(ct)){
// log.info "city equals"
}
else{
// log.info "not eq"
}
def req1=groovyUtils.getXmlHolder( "GetInfoByState#Request" )
req1["//web:USState"]=state[0]
req1.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByState'] )
def respo1= testRunner.testCase.testSteps["GetInfoByState"].testRequest.response.contentAsString
Label labelReq = new Label(j,i,context.testCase.getTestStepByName("GetInfoByZIP").getProperty("request").value)
Label labelReq1 = new Label(j+2,i,context.testCase.getTestStepByName("GetInfoByState").getProperty("request").value)
def response = testRunner.testCase.testSteps["GetInfoByZIP"].testRequest.response.contentAsString
Label labelResp = new Label(j+1,i,response);
Label labelResp1 = new Label(j+3,i,respo1);
writeSheet.addCell(labelReq)
writeSheet.addCell(labelResp);
log.info respo1
writeSheet.addCell(labelReq1)
writeSheet.addCell(labelResp1);
}
}
workbook1.write()
workbook1.close()
很可能是您无意中覆盖了某些内容。我不知道那是什么。但是,一个好的起点是使用更简洁的代码。所以我建议使用 Frosted Sheets(由 Apache POI 支持)而不是 JXL。它使工作簿 MUCH much 的工作变得更加容易。
我写这个库是因为我厌倦了看到一些有史以来最糟糕的代码,而且我知道它可以做得更多......Groovy-ly。
import com.emmanuelrosa.frostedsheets.*
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import groovy.sql.Sql
def projectLocation="E:/"
def dataFileLocation="${projectLocation}zip.xls"
def workbook = new FrostedWorkbook(new HSSFWorkbook(new FileInputStream(dataFileLocation)))
def rowCount = readSheet.getRows()
def colCount = readSheet.getColumns()
def myTestCase = context.testCase
def url = 'jdbc:hsqldb:hsql://localhost/'
def user = 'sa'
def password = ''
def driver = 'org.hsqldb.jdbcDriver'
def sql = Sql.newInstance(url, user, password, driver)
propTestStep = myTestCase.getTestStepByName("Properties");
def workbook1 = FrostedWorkbook.createXLS()
def writeSheet = workbook1['new']
def project = testRunner.testCase.testSuite.project
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
/*
* cellIterator() returns a special Iterator which traverses
* through the cells by row, then column; top-down, left-right.
* It eliminates the need for nested loops.
*/
workbook[0].cellIterator().each { cell ->
req["//web:USZip"] = cell.cellValue
def req=groovyUtils.getXmlHolder( "GetInfoByZIP#Request" )
req.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByZIP'] )
sql.eachRow('select state,city from zip where zip=?',[val]) { row ->
st= row.state
ct= row.city
}
def res=groovyUtils.getXmlHolder( "GetInfoByZIP#Response" )
def state = res.getNodeValues( "//STATE" )
def city=res.getNodeValues("//CITY")
def ct1=city[0]
log.info ct +" " + ct1
if(ct1.equalsIgnoreCase(ct)) {
// log.info "city equals"
}
else{
// log.info "not eq"
}
def req1=groovyUtils.getXmlHolder( "GetInfoByState#Request" )
req1["//web:USState"]=state[0]
req1.updateProperty()
testRunner.runTestStep( project.testSuites['USZipSoap12 TestSuite'].testCases['GetInfoByZIP TestCase'].testSteps['GetInfoByState'] )
writeSheet[cell.rowIndex + 1].with {
def stateInfo = testRunner.testCase.testSteps["GetInfoByState"].testRequest.response.contentAsString
def zipValue = context.testCase.getTestStepByName("GetInfoByZIP").getProperty("request").value
def stateValue = context.testCase.getTestStepByName("GetInfoByState").getProperty("request").value
def zipInfo = testRunner.testCase.testSteps["GetInfoByZIP"].testRequest.response.contentAsString
// Add the columns to the row
append [zipValue, zipInfo, stateValue, stateInfo]
}
}
new FileOutputStream("${projectLocation}output1.xls").withStream { stream ->
workbook1.write(stream)
}
我认为您的响应数据超出了 excel 的单元格限制。您可以通过在 word 中复制粘贴响应来检查该内容,检查那里有多少个字符。 Excel 一行可以包含 32,767 个字符。如果超过这个值,它可能会损坏。