Please before you down vote this, I was not able to find an example of reading a web table and writing it to an Excel file. If you happen to find that link kindly provide it. I have found plenty of examples on how to write to an Excel file but without reading from web table part.
Here is my code:
public class WebTable1 {
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.w3schools.com/html/html_tables.asp");
//tr means Row, this table has 7 rows including Header
///td means Column, this table has 3 columns
//*[#id="customers"]/tbody/tr[2]/td[1]
//*[#id="customers"]/tbody/tr[7]/td[1]
//Notice above the pattern, only the values are changing for tr[??]- which is why we will break it down into 2 String
//below and then concatinate them as String
String beforeXpath_Company = "//*[#id='customers']/tbody/tr["; // changed customer to single quote
String aferXpath_Company = "]/td[1]"; //Company is column 1
String beforeXpath_Contact = "//*[#id='customers']/tbody/tr[";
String aferXpath_Contact = "]/td[2]"; // Contact is column 2
String beforeXpath_Country = "//*[#id='customers']/tbody/tr[";
String aferXpath_Country = "]/td[3]"; // Country is column 3
//Find number of rows so that we do not use hard coded values
List<WebElement> totalRows = driver.findElements(By.xpath("//table[#id='customers']//tr"));
int rows=totalRows.size();
for (int i = 2; i <rows; i++) { //we start from 2 because 1 is column name
String actualXpath = beforeXpath_Company + i + aferXpath_Company;
String companyName = driver.findElement(By.xpath(actualXpath)).getText();
System.out.println(companyName);
String actualXpath_Contact = beforeXpath_Contact + i + aferXpath_Contact;
String contactName = driver.findElement(By.xpath(actualXpath_Contact)).getText();
System.out.println(contactName);
String actualXpath_Country = beforeXpath_Country + i + aferXpath_Country;
String countryName = driver.findElement(By.xpath(actualXpath_Country)).getText();
System.out.println(countryName);
//Try to following to write to an Excel file in C drive
Workbook wb = new HSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet1 = wb.createSheet("Sheet1");
Row row = sheet1.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue(createHelper.createRichTextString(companyName));
FileOutputStream fileOut = new FileOutputStream("C:\\MyTemp\\Test.xls");
wb.write(fileOut);
fileOut.close();
}
}
}
Thanks in advance.
Taking your existing table extraction code, you can do something like this:
public class WebTable1 {
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.w3schools.com/html/html_tables.asp");
String beforeXpath_Company = "//*[#id='customers']/tbody/tr["; // changed customer to single quote
String aferXpath_Company = "]/td[1]"; //Company is column 1
String beforeXpath_Contact = "//*[#id='customers']/tbody/tr[";
String aferXpath_Contact = "]/td[2]"; // Contact is column 2
String beforeXpath_Country = "//*[#id='customers']/tbody/tr[";
String aferXpath_Country = "]/td[3]"; // Country is column 3
//Find number of rows so that we do not use hard coded values
List<WebElement> totalRows = driver.findElements(By.xpath("//table[#id='customers']//tr"));
int rows=totalRows.size();
// Create a workbook and a sheet in it
Workbook wb = new HSSFWorkbook();
Sheet sheet1 = wb.createSheet("Sheet1");
// Create a table header
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("Company name");
row.createCell(1).setCellValue("Contact name");
row.createCell(2).setCellValue("Country");
for (int i = 2; i <rows; i++) { //we start from 2 because 1 is column name
String actualXpath = beforeXpath_Company + i + aferXpath_Company;
String companyName = driver.findElement(By.xpath(actualXpath)).getText();
String actualXpath_Contact = beforeXpath_Contact + i + aferXpath_Contact;
String contactName = driver.findElement(By.xpath(actualXpath_Contact)).getText();
String actualXpath_Country = beforeXpath_Country + i + aferXpath_Country;
String countryName = driver.findElement(By.xpath(actualXpath_Country)).getText();
Row row = sheet1.createRow(i - 1);
row.createCell(0).setCellValue(companyName);
row.createCell(1).setCellValue(contactName);
row.createCell(2).setCellValue(countryName);
}
FileOutputStream fileOut = new FileOutputStream("C:\\MyTemp\\Test.xls");
wb.write(fileOut);
fileOut.close();
}
}
Related
I want to compare two excel sheet data with same column name, excel sheet having same column name but position of column name will be different. So, I need logic first check column name and compare data
below code is working if both the sheet column name have same position or index.
public static void main(String[] args) throws IOException {
// Workbook1 Code
FileInputStream filepath1 = new FileInputStream(".\\DataFile\\Book1.xlsx");
XSSFWorkbook workbook1 = new XSSFWorkbook(filepath1);
XSSFSheet worksheet1 = workbook1.getSheet("sheet1");
int rowcount1 = worksheet1.getPhysicalNumberOfRows();
int CellCount=worksheet1.getRow(0).getPhysicalNumberOfCells();
System.out.println("row count of worbook1:" + rowcount1);
// Workbook2 Code
FileInputStream filepath2 = new FileInputStream(".\\DataFile\\Book2.xlsx");
XSSFWorkbook workbook2 = new XSSFWorkbook(filepath2);
XSSFSheet worksheet2 = workbook2.getSheet("sheet1");
int rowcount2 = worksheet2.getPhysicalNumberOfRows();
System.out.println("row count of worbook2:" + rowcount2);
if (rowcount1 == rowcount2) // condition if rowcount1 is equal to row count of worbook2 are same
{
for (int i = 0; i < rowcount1; i++) {
for(int j=0; j<CellCount; j++)
{
XSSFCell row1 = worksheet1.getRow(i).getCell(j);
XSSFCell row2 = worksheet2.getRow(i).getCell(j);
row1.setCellType(CellType.STRING);
String cellvalue=row1.getStringCellValue();
row2.setCellType(CellType.STRING);
String cellvalue2=row2.getStringCellValue();
if(!cellvalue.equals(cellvalue2))
{
System.out.println("Row number:"+i+ " Column number:"+j+" [ERROR] :" + "Diference in data " +"| Book1 id = " + cellvalue + " | Book2 id = " + cellvalue2);
}
}}}
I tried writing 2 List <WebElement> lists to Excel file using Apache POI. But my method only saves the //column 2 values. //column 1 data not saved in the excel file.
Please help me to resolve this issue.
public void FourthExcel(String classNameOne,String classNameTwo) {
WebDriverWait wait = new WebDriverWait(driver, 40);
wait.pollingEvery(2, TimeUnit.SECONDS);
String filePath = System.getProperty("user.dir");
//Book one
XSSFWorkbook workbookOne = new XSSFWorkbook();
XSSFSheet sheetOne = workbookOne.createSheet("Expenses Sheet");
CommonClass.sleepTime(3000);
WebElement expencesTble = driver.findElement(expencesTable);
wait.until(ExpectedConditions.elementToBeClickable(expencesTble));
List<WebElement> ColOneList = driver.findElements(By.className(classNameOne));
List<WebElement> ColTwoList = driver.findElements(By.className(classNameTwo));
List<Object> ColOneobjectList = Arrays.asList(ColOneList.toArray());
List<Object> ColTwoobjectList = Arrays.asList(ColTwoList.toArray());
int ColumnOneSize = ColOneList.size()-1;
for (int i = 0; i <= ColumnOneSize; i++) {
out.println("For");
out.println(ColOneList.get(i).getText());
//Column 1
XSSFRow rowOneColZero = sheetOne.createRow(i);
rowOneColZero.createCell(0).setCellValue(String.valueOf(ColOneobjectList.get(i)));
//Column 2
XSSFRow rowOneCOlOne = sheetOne.createRow(i);
rowOneCOlOne.createCell(1).setCellValue((RichTextString) ColTwoobjectList.get(i));
}
try {
out.println("try");
FileOutputStream fileOut = new FileOutputStream(filePath + "\\testExcel.xls");
workbookOne.write(fileOut);
workbookOne.close();
} catch (IOException e) {
out.println(e);
}
}
The excel file looks like this:
A1 data is not written into the excel file.
In for loop You override XSSFRow row object, please write like this:
for (int i = 0; i <= ColumnOneSize; i++) {
out.println("For");
out.println(ColOneList.get(i).getText());
//create row
XSSFRow row= sheetOne.createRow(i);
//to Column 1
row.createCell(0).setCellValue(String.valueOf( ColOneobjectList.get(i)));
//to Column 2
row.createCell(1).setCellValue((RichTextString) ColTwoobjectList.get(i));
}
I am using APACHE POI 3.0 to add sheets to existing excel sheet. It works fine.
But as APACHE POI has limitations about making charts, I used a template excel file to create charts, which also worked fine, but this always result in new excel file.
If I have an existing excel sheet and I want to add a sheet, having charts, I am not able to do it. As, when I create charts, I use template file and it always makes a new excel file.
so I was wondering if there is any solution of it of adding sheets to excel, where the sheets have charts
public class TagBrowserSelection
{
private static String[] excelBarPlot_Template = { "","barPlot_1Panel_template.xlsx"};
private static String[] excelPieChart_Template = { "","pieChart_1Panel_template.xlsx"};
private static String[] excelPieAndBarPlot_Template = { "","pieAndBarChart_1Panel_template.xlsx"};
private static String REGEX = "";
static public boolean makeTagBrowserSelection(String strOutputFileName, ArrayList<TagBrowserChildPanel> childList, String sheetName, boolean addSheet, ArrayList<Boolean> chartAttributes)
{
// chart attributes
boolean addBarChart = chartAttributes.get(0);
boolean addPieChart = chartAttributes.get(1);
boolean addNoTag = chartAttributes.get(2);
boolean addZeros = chartAttributes.get(3);
REGEX = "^" + sheetName;
Pattern p = Pattern.compile(REGEX);
String[] templateArray = null;
if (addBarChart && addPieChart)
templateArray = excelPieAndBarPlot_Template;
else if (addBarChart)
templateArray = excelBarPlot_Template;
else if (addPieChart)
templateArray = excelPieChart_Template;
try
{
int number = childList.size();
XSSFWorkbook workbook = null;
XSSFWorkbook wb = null;
XSSFSheet sheet = null;
int col_num = 0;
int row_num = 0;
XSSFRow row = null;
XSSFCell cell = null;
// if adding sheet to existing excel file
if (addSheet)
{
FileInputStream fis = new FileInputStream(new File(strOutputFileName));
workbook = new XSSFWorkbook(fis);
fis.close();
// number of existing sheets in excel file
int numberOfSheets = workbook.getNumberOfSheets();
// check is sheetName exists already
if (isSheetExist(sheetName, workbook))
{
int counter = 1;
for (int ii = 0; ii < numberOfSheets; ii++)
{
Matcher m = p.matcher(workbook.getSheetName(ii));
if (m.find())
counter++;
}
sheetName = sheetName + " (" + counter + ")";
}
}
else
{
workbook = new XSSFWorkbook();
}
======================================================================
// if template file needs to be used(if bar chart/pie chart option is selected)
if (templateArray != null)
{
InputStream is = TagBrowserSelection.class.getClassLoader().getResourceAsStream(templateArray[number]);
wb = new XSSFWorkbook(OPCPackage.open(is));
sheet = wb.getSheetAt(0);
// wb.close();
}
else
{
sheet = workbook.createSheet(sheetName);
}
// Freeze top two row
// sheet.createFreezePane(0, 1, 0, 1);
// Filling up the workbook and performing the row/column formatting
for (TagBrowserChildPanel child : childList)
{
// Check if row is already created before(previous tag category)
row = sheet.getRow(0);
if (row == null)
row = sheet.createRow(0);
// Adding tag category name as header
String tagCategory = child.getSelectedCategory().getName();
cell = row.createCell(col_num);
cell.setCellValue(tagCategory);
row = sheet.getRow(1);
if (row == null)
row = sheet.createRow(1);
// Adding column headers
cell = row.createCell(col_num);
cell.setCellValue("tag");
cell = row.createCell(col_num + 1);
cell.setCellValue("counts");
row_num = 2;
// Adding tag category document summary(name and counts)
ArrayList<TagSummaryItem> tagSummary = child.getTagChartCounts();
for (int i = 0; i < tagSummary.size(); i++)
{
// Check if row is already created before(previous tag category)
row = sheet.getRow(row_num);
if (row == null)
row = sheet.createRow(row_num);
cell = row.createCell(col_num);
if (!addNoTag)
{
if (tagSummary.get(i).m_strTag == "[No Tag]")
continue;
}
if (!addZeros)
{
if (tagSummary.get(i).m_nCount == 0)
continue;
}
cell.setCellValue(tagSummary.get(i).m_strTag);
cell = row.createCell(col_num + 1);
cell.setCellValue(tagSummary.get(i).m_nCount);
row_num++;
}
// auto-size of tag column
sheet.autoSizeColumn(col_num);
col_num = col_num + 3;
}
FileOutputStream out = new FileOutputStream(strOutputFileName);
if (templateArray != null)
{
wb.setSheetName(0, sheetName);
wb.write(out);
wb.close();
}
else
{
workbook.write(out);
workbook.close();
}
out.close();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
Above is my code, its one code. I split into two sections. Section is the one which uses template to make chart excel sheet.
there's the method cloneSheet() in the HSSFWorkbook class. Try it.
1) I am trying to read the values from the webtable of an appliation and write it into the excel sheet one by one.
2) There are 4 values in each row of the webtable that need to be written to excel sheet, but there are some images in each row that i'm ignoring bu using below code.
text.length()>2
.
3) There will be 200-300 rows in webtable that need to be fetched and written to excel sheet.
This is the code i have tried. But i dont know how to write it into each row of the excel sheet one by one. Please help me in this regard.
//get the table
WebElement statusTable = browser.findElement(By.id("projectstatus"));
//Get all the rows in the table
List<WebElement> allRows = statusTable.findElements(By.tagName("tr"));
//Get the size(row no) of allRows
int rowSize = allRows.size();
System.out.println(rowSize);
for (WebElement row : allRows) {
//Get all cell values in each row
List<WebElement> allCells = row.findElements(By.tagName("td"));
//System.out.println(allCells.size());
if(allCells.size() > 1){
for (WebElement cell : allCells) {
String text = cell.getText();
if(text.length()>2){
String value = cell.getText();
}
}
}
// locate the test xl file
File file = new File("e:\\Testing_emi.xls");
// create input stream
FileInputStream fis = new FileInputStream(file);
// create workbook
HSSFWorkbook wb = new HSSFWorkbook(fis);
// get sheet
HSSFSheet sheet1 = wb.getSheet("Sheet1");
// get rows
HSSFRow row = sheet1.getRow(1);
HSSFCell cellEx = row.getCell(0);
if (cellEx == null) {
cellEx = row.createCell(0);
}
cellEx.setCellValue(value);
//get the table
WebElement statusTable = browser.findElement(By.id("projectstatus"));
//Get all the rows in the table
List<WebElement> allRows = statusTable.findElements(By.tagName("tr"));
//Get the size(row no) of allRows
int rowSize = allRows.size();
System.out.println(rowSize);
// locate the test xls file
File file = new File("e:\\Testing_emi.xls");
// create input stream
FileInputStream fis = new FileInputStream(file);
// create workbook
HSSFWorkbook wb = new HSSFWorkbook(fis);
// get sheet
HSSFSheet sheet1 = wb.getSheet("Sheet1");
// get rows
HSSFRow row;
for (int i=0; i<rowSize; i++)
{
WebElement webRow = allRows.get(i);
//Get all cell values in each row
List<WebElement> allCells = webRow.findElements(By.tagName("td"));
//System.out.println(allCells.size());
if(allCells.size() > 1)
{
HSSFRow excelRow = sheet1.createRow(i);
for (int j=0; j<allCells.size(); j++)
{
WebElement webCell = allCells.get(j);
String text = webCell.getText();
if(text.length()>2)
{
Cell excelCell = excelRow.createCell();
excelCell.setValue(webCell.getText());
}
}
}
}
sheet1.close();
Read the values from the Web Table of an application and write it in to the excel sheet one by one.There are 5 values in each row of the Web Table and that need to written in Excel sheet. Below is the working code.
System.setProperty("webdriver.chrome.driver","C:\\Users\\Documents\\Selenium jars\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://cosmocode.io/automation-practice-webtable/");
WebElement table = driver.findElement(By.xpath("//*[#id='countries']/tbody"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
int rowcount = rows.size();
FileOutputStream fis = new FileOutputStream(new File("C:\\Users\\Documents\\Selenium\\output.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sh = wb.createSheet("First Sheet");
for (int row = 0; row < rowcount; row++) {
List<WebElement> columns_inrow = rows.get(row).findElements(By.tagName("td"));
int columns_count = columns_inrow.size();
System.out.println("Number of cells in Row " + row + " are " + columns_count);
Row ro = sh.createRow(row);
for (int column = 0; column < columns_count; column++) {
String celltext = columns_inrow.get(column).getText();
System.out.println(
"Cell Value of row number " + row + " and column number " + column + " Is " + celltext);
ro.createCell(column).setCellValue(celltext);
}
System.out.println("===========================");
}
wb.write(fis);
wb.close();
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I went through some sample codes to export data to excel using Apache POI. However, I am not sure as to how we can export database query results to an excel file. I know that we must create cells in rows and then set values to the cell. But I already have the data in the resultset and must just export the same to an excel file. Can anyone provide me a small/easy code to do the same.
Thanks!
Try : Reference Apache POI's Developer Guide
Example Person table :
+------------------+
| NAME | ADDRESS |
+------------------+
| Jhone | USA |
| Smith | USA |
+------------------+
Example Program
Workbook wb = new HSSFWorkbook();
Sheet personSheet = wb.createSheet("PersonList");
Row headerRow = personSheet.createRow(0);
Cell nameHeaderCell = headerRow.createCell(0);
Cell addressHeaderCell = headerRow.createCell(1);
String sql = "select name, address from person_table";
PrepareStatement ps = connection.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
int row = 1;
while(resultSet.next()) {
String name = resultSet.getString("name");
String address = resultSet.getString("address");
Row dataRow = personSheet.createRow(row);
Cell dataNameCell = dataRow.createCell(0);
dataNameCell.setCellValue(name);
Cell dataAddressCell = dataRow.createCell(1);
dataAddressCell.setCellValue(address);
row = row + 1;
}
String outputDirPath = "D:/PersonList.xls";
FileOutputStream fileOut = new FileOutputStream(outputDirPath);
wb.write(fileOut);
fileOut.close();
For HSSF format it is possible to use a Cocoon pipeline that delivers the results of a database query as XML to the POI serializer.
This has the advantage of not entangling the database query with the calling of the POI API.
I am investigating the amount of work required to upgrade the serializer to handle the XSSF format to overcome the 64k limit on the number of rows in the final speadsheet.
if youre using (or you can use) SqlResultSet then this solution fits you:
https://github.com/OfekRv/DraggerReports/blob/master/src/main/java/dragger/bl/exporter/ExcelReportExporter.java
public class ExcelReportExporter implements ReportExporter {
private static final char UNDER_LINE = '_';
private static final char SPACE = ' ';
private static final String SUFFIX = ".xlsx";
private static final int TITLE_ROW = 0;
private static final int HEADER_ROW = 3;
private static final int RESULTS_FIRST_ROW = HEADER_ROW + 1;
private static final int FIRST_COLUMN_INDEX = 0;
#Inject
QueryGenerator generator;
#Inject
QueryExecutor executor;
#Override
public File export(Report reportToExport) throws DraggerExportException {
String reportName = generateReportName(reportToExport);
SqlRowSet results = executor.executeQuery(generator.generate(reportToExport.getQuery()));
SqlRowSetMetaData resultsMetaData = results.getMetaData();
try (Workbook workbook = new XSSFWorkbook();) {
Sheet sheet = workbook.createSheet(reportName);
createTitle(reportToExport, workbook, sheet);
createHeaderRowFromMetadata(resultsMetaData, workbook, sheet);
int excelRowIndex = createDataTableFromResultset(results, resultsMetaData, workbook, sheet);
setTableAutoFilter(resultsMetaData, sheet, excelRowIndex);
saveExcelFile(reportName, workbook);
autoSizeColumns(resultsMetaData, sheet);
} catch (IOException e) {
throw new DraggerExportException("Could not create export file", e);
}
return new File(reportName);
}
private String generateReportName(Report reportToExport) {
return reportToExport.getName().replace(SPACE, UNDER_LINE) + UNDER_LINE + LocalDate.now() + SUFFIX;
}
private void autoSizeColumns(SqlRowSetMetaData resultsMetaData, Sheet sheet) {
for (int i = FIRST_COLUMN_INDEX; i < resultsMetaData.getColumnCount(); i++) {
sheet.autoSizeColumn(i);
}
}
private void saveExcelFile(String reportName, Workbook workbook) throws IOException, FileNotFoundException {
try (FileOutputStream fileOut = new FileOutputStream(reportName);) {
workbook.write(fileOut);
}
}
private void setTableAutoFilter(SqlRowSetMetaData resultsMetaData, Sheet sheet, int excelRowIndex) {
sheet.setAutoFilter(new CellRangeAddress(HEADER_ROW, excelRowIndex, FIRST_COLUMN_INDEX,
resultsMetaData.getColumnCount() - 1));
}
private int createDataTableFromResultset(SqlRowSet results, SqlRowSetMetaData resultsMetaData, Workbook workbook,
Sheet sheet) {
int excelRowIndex = RESULTS_FIRST_ROW;
CellStyle DataStyle = createDataCellStyle(workbook);
while (results.next()) {
Row row = sheet.createRow(excelRowIndex);
for (int i = FIRST_COLUMN_INDEX; i < resultsMetaData.getColumnCount(); i++) {
CreateCell(results.getObject(resultsMetaData.getColumnNames()[i]).toString(), DataStyle, row, i);
}
excelRowIndex++;
}
return excelRowIndex;
}
private void createHeaderRowFromMetadata(SqlRowSetMetaData resultsMetaData, Workbook workbook, Sheet sheet) {
Row headerRow = sheet.createRow(HEADER_ROW);
CellStyle headerStyle = createHeaderCellStyle(workbook);
for (int i = FIRST_COLUMN_INDEX; i < resultsMetaData.getColumnCount(); i++) {
CreateCell(resultsMetaData.getColumnNames()[i], headerStyle, headerRow, i);
}
}
private void CreateCell(String data, CellStyle DataStyle, Row row, int cellIndex) {
Cell cell = row.createCell(cellIndex);
cell.setCellValue(data);
cell.setCellStyle(DataStyle);
}
}