I have a file stored in blob in the database and I'm able to download the file on click to excel. Problem is that the header is coming in one line in spread on different columns because of after each column
"\"\t\"" "\t"
how to fix these
ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out, "ISO8859_1");
ecsvp_en = new ExcelCSVPrinter(osw);
String[] headers = list.get(0);
//Column Headers
ecsvp_en.println(headers);
// Data
int rowCount;
for (rowCount = 1; rowCount < list.size(); rowCount++) {
row = list.get(rowCount);
ecsvp_en.println(row);
}
Actual header :
"Contract Record Type\"\t\"Contract Type\"\t\"Contract Number\"\t\"Original Contract: Contract Number\"\t\"Contract Line Item Number\"\t\"Product: Product Name\"\t\"Name\"\t\"BMT #\"\t\"Service Status\"\t\"Created Date\"\t\"Effective Date"
Expected header :
"Contract Record Type\tContract Type\tContract Number\tOriginal Contract: Contract Number\tContract Line Item Number\tProduct: Product Name\tName\tBMT #\tService Status\tCreated Date\tEffective Date"
Related
I want to write data in a specific column based on the column header title and an attribute of the data to be written. For example, if I have 3 columns, first column with header title "aaa", second column with header title "bbb" and third column with header title "ccc". Then I have an object like this: Data data = new Data(int id, String header) and the constructor set the attributes this.id = id and this.header = header... if the header is equals to "aaa" I want to write the data.id in the column "aaa", if it is "bbb" in the "bbb", if it is "ccc" in the "ccc" column.
Here an example code:
private void writeInSpecificColumn(Data data) {
XSSFWorkbook wb = this.getWorkbook();
XSSFSheet st = this.getSheet();
if (data.header.equals("aaa")) {
// write data.id in the column with header "aaa"
} else if (data.header.equals("bbb")) {
// write data.id in the column with header "bbb"
} else {
// write data.id in the column with header "ccc"
}
}
Obviously, before doing this, I write the header columns in this way:
private void writeHeaders() throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("ok");
Row row = sheet.createRow(0);
int counter = 1;
String[] headers = {"aaa", "bbb", "ccc"};
for (int i = 0; i < 3; i++) {
Cell cell = row.createCell(counter);
cell.setCellValue(headers[i]);
}
FileOutputStream outputStream = new FileOutputStream("ok.xlsx");
try (outputStream) {
workbook.write(outputStream);
}
workbook.close();
}
I am trying to fetching data from excel sheet(.xlsx) file. when I use to print fetched data using
System.out.println(sheet.getRow(i).getCell(c).getStringCellValue()); I see the all the rows from excel sheet is fetched. But when I add this data in jtable it misses last three rows and shows following error:
Cannot invoke "org.apache.poi.xssf.usermodel.XSSFRow.getCell(int)" because the return value of "org.apache.poi.xssf.usermodel.XSSFSheet.getRow(int)" is null
enter code here
JFileChooser fileChooser = new JFileChooser("D:");
int returnValue = fileChooser.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
selectedFile = fileChooser.getSelectedFile();
FileName = selectedFile.getName();
String FilePath = selectedFile.getPath();
System.out.println(FileName);
System.out.println(FilePath);
File excelfile = new File(FileName);
try{
FileInputStream fis = new FileInputStream(selectedFile);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheetAt(0);
int totalrows = sheet.getPhysicalNumberOfRows();
for (int i = 0; i <=totalrows; )
{
dmodel.addRow(new Object[]{"" });
System.out.println(sheet.getRow(i).getCell(0).getStringCellValue()); // this line work
String name = sheet.getRow(i).getCell(0).getStringCellValue();
jTable1.setValueAt(name , i, 0); // this line does not work
i++ ;
}
JOptionPane.showMessageDialog(null, "All rows are fetched Successfully" );
}catch(Exception fx)
{
System.out.println(fx.getMessage());
// System.out.println(fx.getCause());
}
System.out.println(sheet.getRow(r).getCell(c).getStringCellValue()); // this line work
String name = sheet.getRow(i).getCell(c).getStringCellValue();
jTable1.setValueAt(name , i, 0); // this line does not work
Don't know if this will solve your problem, but the above code is not how you use System.out.println(...) to debug your logic.
To verify the data you use:
//System.out.println(sheet.getRow(r).getCell(c).getStringCellValue()); // this line work
String name = sheet.getRow(i).getCell(c).getStringCellValue();
System.out.println( name );
jTable1.setValueAt(name , i, 0); // this line does not work
Don't attempt to read the data twice. By assigning the data to a variable you are debugging the data in the variable. Don't repeat the nested methods multiple times.
Maybe the class expects you to only read the data once, so the second read gives the null value. The simple change above will prevent this.
My requirement is to read the excel dynamically and store the contents in Map. The headers should be key and the respective column should be value so that when I pass the key, I can get the cell value.
My Excel sheet contains multiple rows and columns which can be changed dynamically. My intention is to write a common function in java to read an excel and store the contents in map. The Key should be column headers and the value should be respective cell value of the header. So while retrieving when I pass the header key, I should receive the respective cell value. My plan is to pass the row number and the key in a method so that it can retrieve the respective cell value related to the row as well as the key
static Map<String> excelMap = new LinkedHashMap<String>();
public static String readWriteExcel(String sheetName) throws EncryptedDocumentException, InvalidFormatException, IOException, JSONException
{
File file = new File("File Path");
FileInputStream inputStream = new FileInputStream( file );
Workbook workbook = WorkbookFactory.create( inputStream );
Sheet sheet = workbook.getSheet( sheetName );
int rowNumber =0;
int rowCount = sheet.getLastRowNum();
for(int i=1;i<=rowCount;i++){
Row row = sheet.getRow(0);
for(int j=0;j<row.getLastCellNum();j++) {
String key=row.getCell(j).getStringCellValue();
String value=sheet.getRow(rowNumber+1).getCell(j).getStringCellValue();
excelMap.put(key, value);
}
}
}
By looking at the code, i am assuming the issues: Multiple rows present in the sheet, but you are getting data of first row only.
Solution :
First of all, you need to store all rows data in a List of Map. where list index corresponds to the row number. Also You are not incrementing the rowNumber variable anywhere. Its always 0.
Why not directly use the variable i to get a particular row from sheet?
I think this should work.
static List<Map<String, String>> excelData = new ArrayList<HashMap<String, String>>();
public static String readWriteExcel(String sheetName) throws EncryptedDocumentException, InvalidFormatException, IOException, JSONException
{
File file = new File("File Path");
FileInputStream inputStream = new FileInputStream( file );
Workbook workbook = WorkbookFactory.create( inputStream );
Sheet sheet = workbook.getSheet( "sheetName" );
int rowCount = sheet.getLastRowNum();
for(int i=1;i<=rowCount;i++){
Row row = sheet.getRow(0);
Map<String,String> rowData = new HashMap<>();
for(int j=0;j<row.getLastCellNum();j++) {
String key=row.getCell(j).getStringCellValue();
String value=sheet.getRow(i).getCell(j).getStringCellValue();
rowData.put(key, value);
}
excelData.add(rowData);
}
}
Since you want to map multiple rows you have to store multiple rows.
One way is storing a map consisting column->list containing values for each row.
Another way is storing a map consisting column+row number->value.
Sample code for second method:
static Map<String, String> excelMap = new LinkedHashMap<String, String>();
...
// storing values
excelMap.put(key + "_" + i, value); // i is row index
...
// getting values
public static String getCellValue(String cellName, int rowIndex) {
return excelMap.get(cellName + "_" + rowIndex);
}
I have a problem with adding headers to the newly created .xlsx file
I would like to see the first header = 'UserName' and the second header = 'Password'. Can anyone help me on how to do this?
XSSFWorkbook new_workbook = new XSSFWorkbook(); // create a blank workbook object
XSSFSheet sheet = new_workbook.createSheet("EMP_DETAILS"); // create a worksheet with caption score_details
// Define the SQL query
String sql = "SELECT login, password FROM \"Permissions\"";
ResultSet rs = stmt.executeQuery(sql);
// Create Map for Excel Data
Map<String, Object[]> excel_data = new HashMap<String, Object[]>();
int row_counter = 0;
//Extract data from result set
while(rs.next()){
row_counter = row_counter+1;
String login = rs.getString("login");
String password = rs.getString("password");
excel_data.put(Integer.toString(row_counter), new Object[] {login, password});
}
rs.close();
// Load data into logical worksheet
Set<String> keyset = excel_data.keySet();
int rownum = 0;
for(String key : keyset){ // loop through the data and add them to the cell
Row row = sheet.createRow(rownum++);
Object [] objArr = excel_data.get(key);
int cellnum = 0;
for(Object obj : objArr){
Cell cell = row.createCell(cellnum++);
if(obj instanceof Double)
cell.setCellValue((Double)obj);
else
cell.setCellValue((String)obj);
}
}
FileOutputStream output_file = new FileOutputStream(new File("File.xlsx")); // create XLSX file
new_workbook.write(output_file); // write excel document to output stream
output_file.close(); // close the file
My $0.02... don't create an Excel file for something this simple. Instead create a CSV file. The first line you write will be
UserName, Password
for the headers and the lines after that will just be your data for each column separated by a comma. Once the file is written, you can easily open it in Excel and save it as an Excel file.
This method is way simpler and easier than trying to actually write an Excel file.
If you don't want to do that, you just need to create a row before you start looping through your keyset as you would any other row and write the strings for headers.
You can use following code after this line ResultSet rs = stmt.executeQuery(sql);:
ResultSetMetaData rsmd=rs.getMetaData();
Then to fetch column headers; use below:
String columnName1 = rsmd.getColumnName(1); // will fetch you "UserName"
String columnName2 = rsmd.getColumnName(2); // will fetch you "Password"
I am executing a query which is returning a ResultSet object. I want to convert this ResultSet into a CSV String in memory.
The reason I want to do this is that once I have the CSV String, I want to invoke a REST API endpoint and pass it this CSV data.
Are there any existing libraries or utilities I can use to convert from a ResultSet into an in memory String? I.e. not into a file..
StringWriter output = new StringWriter();
CsvWriterSettings settings = new CsvWriterSettings(); // many options here, check the documentation
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
String[] headers = new String[columns];
for(int i = 1; i <= columns; i++){
headers[i - 1] = md.getColumnLabel(i);
}
//if an input value is null, you may want print "NULL"
settings.setNullValue("NULL");
// if an input value is not null, but is empty (e.g. ""), the writer can be configured to print "NULL" as well
settings.setEmptyValue("NULL");
// Sets the file headers (used for finer selection of fields, these values won't be written automatically)
settings.setHeaders(headers);
// Creates a writer with the above settings;
CsvWriter writer = new CsvWriter(output, settings);
// Writes the headers specified in the settings
writer.writeHeaders();
Object[] row = new Object[columns];
while(rs.next()){
for(int i = 1; i <= columns; i++){
row[i - 1] = rs.getObject(i);
}
writer.writeRow(row);
}
writer.close();
String yourString = output.toString();