Export data from database to xlsx file (Excel) using spring - excel

I need to export data from database to excel document using spring.
But when I download from controller document I get message that is currupted file or wrong extension.
private static final String EXCEL_FILE_NAME = "UserExcelExport.xlsx";
#GetMapping("/download")
public void download(HttpServletResponse response) throws Exception {
List<User> users = userService.getUsers();
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("All Users List");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("Username");
header.createCell(1).setCellValue("First name");
header.createCell(2).setCellValue("Last name");
header.createCell(3).setCellValue("E-mail");
int rowNum = 1;
for (User user : users) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(user.getUsername());
row.createCell(1).setCellValue(user.getFirstName());
row.createCell(2).setCellValue(user.getLastName());
row.createCell(3).setCellValue(user.getEMail());
}
response.setHeader("Content-disposition", "attachment; filename=" + EXCEL_FILE_NAME);
workbook.write(response.getOutputStream());
}

It is missing the content-type:
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Also use XSSFWorkbook to generate an .xlsx file:
XSSFWorkbook wb = new XSSFWorkbook();
Edit~~~~
Here is a full example that works, I use SpringBoot 2.2.2 and POI 3.15.
#GetMapping(value = "/main/export")
public void export(HttpServletResponse response) throws Exception {
// user list
List<UserDto> users = new ArrayList<>();
users.add(new UserDto(1L, "user1"));
users.add(new UserDto(2L, "user2"));
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("All Users List");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("Username");
header.createCell(1).setCellValue("First name");
header.createCell(2).setCellValue("Last name");
header.createCell(3).setCellValue("E-mail");
int rowNum = 1;
for (UserDto user : users) {
Row aRow = sheet.createRow(rowNum++);
aRow.createCell(0).setCellValue(user.getId());
aRow.createCell(1).setCellValue(user.getName());
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("content-disposition", "attachment; filename=myfile.xlsx");
workbook.write(response.getOutputStream());
}

I have same problm.
I tried using you suggestion.
#GetMapping("/download")
public void download(HttpServletResponse response) throws Exception {
List<User> users = userService.getUsers();
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("All Users List");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("Username");
header.createCell(1).setCellValue("First name");
header.createCell(2).setCellValue("Last name");
header.createCell(3).setCellValue("E-mail");
int rowNum = 1;
for (User user : users) {
Row aRow = sheet.createRow(rowNum++);
aRow.createCell(0).setCellValue(user.getUsername());
aRow.createCell(1).setCellValue(user.getFirstName());
aRow.createCell(2).setCellValue(user.getLastName());
aRow.createCell(3).setCellValue(user.getEMail());
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("content-disposition", "attachment; filename=myfile.xlsx");
workbook.write(response.getOutputStream());
}
But when I download from controller document i get this:

Related

SXSSFWorkbook generates corrupted Excel file(xlsx) randomly with Apache POI 412

SXSSFWorkbook generates corrupted file randomly with Apache POI 412. This issue happens randomly and Once we clear the Cache in the weblogic application server and re-start the server and it works fine. Again after sometime we face the same issue. please find the below sample program and let me know how we can fix this issue.
// Java program to write data in excel sheet using java code
public class TestExcel {
private static final String HEADER_FONT = "Calibri";
private static final short HEADER_FONT_Height = 11;
// any exceptions need to be caught
public static void main(String[] args) throws Exception
{
System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.SystemOutLogger" );
System.setProperty("poi.log.level", POILogger.DEBUG + "");
// workbook object
SXSSFWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook(), 100, true, true);
workbook.setCompressTempFiles(true);
String workSheetName = "AddressBookData";
// Create a sheet
System.out.println("Before Calling workbook.createSheet");
Sheet spreadsheet = workbook.createSheet(workSheetName);
System.out.println("After Calling workbook.createSheet");
//Create a Font for styling header cells
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerFont.setFontName(HEADER_FONT);
headerFont.setFontHeightInPoints(HEADER_FONT_Height);
// Create a CellStyle with the font
CellStyle headerCellStyle = workbook.createCellStyle();
headerCellStyle.setFont(headerFont);
CellReference cellReference = new CellReference("A1");
int rowIndex = cellReference.getRow();
int colIndex = cellReference.getCol();
// Create a Row
Row row = spreadsheet.createRow(rowIndex);
int headerColIndex = colIndex;
// This data needs to be written (Object[])
Map<String, Object[]> addressBookData= new TreeMap<String, Object[]>();
addressBookData.put("1", new Object[] { "Address Number", "Alpha Name", "Sch Typ" });
addressBookData.put("2", new Object[] { "1", "Financial/Distribution Company", "E" });
addressBookData.put("3", new Object[] { "2", "4242", "C" });
addressBookData.put("4", new Object[] { "3", "DITTest","E" });
addressBookData.put("5", new Object[] { "4", "DITTest4","E" });
addressBookData.put("6", new Object[] { "12", "Test1","E" });
addressBookData.put("7", new Object[] { "13", "Test2","E" });
addressBookData.put("8", new Object[] { "14", "Test3","E" });
addressBookData.put("9", new Object[] { "21", "Test4","E" });
Set<String> keyid = addressBookData.keySet();
int rowid = 0;
// writing the data into the sheets...
for (String key : keyid) {
row = spreadsheet.createRow(rowid++);
Object[] objectArr = addressBookData.get(key);
int cellid = 0;
for (Object obj : objectArr) {
if (rowid == 1)
{
Cell headerCell = row.createCell(cellid++);
headerCell.setCellValue((String)obj);
headerCell.setCellStyle(headerCellStyle);
}
else
{
Cell cell = row.createCell(cellid++);
cell.setCellValue((String)obj);
}
}
}
// .xlsx is the format for Excel Sheets...
// writing the workbook into the file...
FileOutputStream out = new FileOutputStream( new File("AB.xlsx"));
workbook.write(out);
out.close();
// Closing the workbook
workbook.close();
// Delete the the temp file
workbook.dispose();
}
}

Return particular sheet from Workbook in byte[]

I have this excel workbook stored in my resources folder. Considering this excel is of 9 pages i want to extract a particular page and return it into from of byte[].
I created this controller
#GetMapping(value = "/getSinglePage/{pageNumber}")
private ResponseEntity<byte[]> getExcelByPageNumber(#PathVariable Integer pageNumber) throws IOException {
return new ResponseEntity<>(service.getExcelByPageNumber(pageNumber), HttpStatus.OK);
}
The service code contains--
public byte[] getExcelByPageNumber(Integer pageNumber) throws IOException {
Workbook workbook = null;
byte[] byteArray = null;
// here file.xls is my excel sheet that contains 9 sheet for example
workbook = WorkbookFactory.create(loader.getResource("classpath:file.xls").getInputStream());
//gets the sheet from given page number
Sheet sheet = workbook.getSheetAt(pageNumber);
// now i want to return this sheet in the form of byte[]
return byteArray;
}
How should I return it into form of byte[]?
By doing some POC I get to know a single worksheet could not exist without having its own workbook. And Workbook has restricted libraries to work on. So apparently I could not find any direct solution to copy or append the sheet.
What i did is I removed the sheets which are not needed that is keeping only sheet in the workbook and then writing it using ByteArrayOutputStream.
public byte[] getExcelByPageNumber(Integer pageNumber) throws IOException {
// TODO Auto-generated method stub
Workbook workbook = new XSSFWorkbook();
workbook = WorkbookFactory.create(loader.getResource("classpath:file.xls").getInputStream());
Sheet tmpSheet = workbook.getSheetAt(pageNumber - 1);
for (int i = workbook.getNumberOfSheets() - 1; i >= 0; i--) {
String sheetName = workbook.getSheetName(i).trim();
if (!tmpSheet.getSheetName().equals(sheetName)) {
workbook.removeSheetAt(i);
}
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
workbook.write(bos);
} finally {
bos.close();
}
byte[] bytes = bos.toByteArray();
return bytes;
}

Not able to run java code from Eclipse to Jmeter using Groovy

The code below prints the content from the excel file (tried in eclipse) but I am not able to run it in Jmeter 3.1 using Groovy.
I throws error:
Problem in JSR223 script JSR223 Sampler, message:
javax.script.ScriptException:
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed
This is my code:
public static void main (String args[]) throws IOException
{
GetExcelTableInto2DArrayListString("C:\\Users\\val1\\Desktop\\Book1.xlsx", true);
}
public static void GetExcelTableInto2DArrayListString(String excelFile, boolean debug) throws IOException{
ArrayList<String> OUT = new ArrayList<String>();
File myFile = new File(excelFile);
FileInputStream fis = null;
fis = new FileInputStream(myFile);
String columnWanted = "PhysicalIDs";
Integer columnNo = null;
XSSFWorkbook myWorkBook = null;
myWorkBook = new XSSFWorkbook (fis);
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
// Get iterator to all the rows in current sheet
List<Cell> cells = new ArrayList<Cell>();
Row firstRow = mySheet.getRow(0); //rowIterator.next();
for(Cell cell:firstRow){
if (cell.getStringCellValue().equals(columnWanted)){
columnNo = cell.getColumnIndex();
}
}
System.out.println(columnNo);
DataFormatter formatter = new DataFormatter(Locale.US);
if (columnNo != null){
for (Row row : mySheet) {
Cell c = row.getCell(columnNo);
System.out.println(formatter.formatCellValue(c));
if (c == null) {
// Nothing in the cell in this row, skip it
} else {
cells.add(c);
}
}
}else{
System.out.println("could not find column " + columnWanted + " in first row of " + myFile.toString());
}
}
I strongly doubt that your code works in eclipse (whatever it is) and anywhere else because this line:
public static void main (String args[])
is not syntactically correct neither in Java nor in Groovy.
The "good" declaration of the entry point (although it's not required for Groovy scripts) would be:
public static void main(String[] args)
Full code just in case:
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.DataFormatter
import org.apache.poi.ss.usermodel.Row
import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
public static void main(String[] args) throws IOException {
GetExcelTableInto2DArrayListString("C:\\Users\\val1\\Desktop\\Book1.xlsx", true);
}
public static void GetExcelTableInto2DArrayListString(String excelFile, boolean debug) throws IOException {
ArrayList<String> OUT = new ArrayList<String>();
File myFile = new File(excelFile);
FileInputStream fis = null;
fis = new FileInputStream(myFile);
String columnWanted = "PhysicalIDs";
Integer columnNo = null;
XSSFWorkbook myWorkBook = null;
myWorkBook = new XSSFWorkbook(fis);
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
// Get iterator to all the rows in current sheet
List<Cell> cells = new ArrayList<Cell>();
Row firstRow = mySheet.getRow(0); //rowIterator.next();
for (Cell cell : firstRow) {
if (cell.getStringCellValue().equals(columnWanted)) {
columnNo = cell.getColumnIndex();
}
}
System.out.println(columnNo);
DataFormatter formatter = new DataFormatter(Locale.US);
if (columnNo != null) {
for (Row row : mySheet) {
Cell c = row.getCell(columnNo);
System.out.println(formatter.formatCellValue(c));
if (c == null) {
// Nothing in the cell in this row, skip it
} else {
cells.add(c);
}
}
} else {
System.out.println("could not find column " + columnWanted + " in first row of " + myFile.toString());
}
}
More information:
Lesson: A Closer Look at the "Hello World!" Application
Busy Developers' Guide to HSSF and XSSF Features
Apache Groovy - Why and How You Should Use It

How to Export DataTable into Excel

I have list of objects and i converted those into data table now i am unable to export those into excel
Below is the sample code
class Program
{
static void Main(string[] args)
{
Student s1 = new Student("Student-A",100);
Student s2 = new Student("Student-B", 90);
Student s3 = new Student("Student-C", 80);
List<Student> studentList = new List<Student>() { s1,s2,s3};
ListToDataTable converter = new ListToDataTable();
DataTable dt = converter.ToDataTable(studentList);
Console.WriteLine();
}
}
Below is the student class which has two properties
class Student
{
public string Name { get; set; }
public int? Score { get; set; }
public Student(string name,int? score)
{
this.Name = name;
this.Score = score;
}
}
Below is the class used for converting list of objects to data table
public class ListToDataTable
{
public DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
dataTable.Columns.Add(prop.Name);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
}
Try to create a simple CSV file from your DataTable.
You can use the following DataTable extension, after you have converted your list to a DataTable.
public static string ToCSV(this DataTable table)
{
var result = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(table.Columns[i].ColumnName);
result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
}
foreach (DataRow row in table.Rows)
{
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(row[i].ToString());
result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
}
}
return result.ToString();
}
Example of usage :
// replace with your data table here
DataTable dt = new DataTable();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(dt.ToCSV());
MemoryStream stream = new MemoryStream(bytes);
StreamReader reader = new StreamReader(stream);
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment;filename={0}.csv", "filename"));
Response.ContentType = "application/text";
Response.ContentEncoding = Encoding.Unicode;
Response.Output.Write(reader.ReadToEnd());
Response.Flush();
Response.End();
Since you have this tagged as interop, I went that route (no need to create a csv file, just export directly to excel).
This solution is not the prettiest, but it works. I've also changed it some as you can export your studentList directly to excel (no need to convert it to a dataTable first).
First thing, in your solution, you need to add a reference to "Microsoft.Office.Interop.Excel". To do this, right click on "References" in Solution Explorer, then "Add Reference", then click on the ".NET" tab, then scroll down to find it.
Once that is done, update your code as follows:
using System;
using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
static void Main()
{
var s1 = new Student("Student-A", 100);
var s2 = new Student("Student-B", 90);
var s3 = new Student("Student-C", 80);
var studentList = new List<Student> { s1, s2, s3 };
// Create an excel sheet
var xlApp = new Excel.Application { Visible = true }; // Create instance of Excel and make it visible.
xlApp.Workbooks.Add(Excel.XlSheetType.xlWorksheet); // Create a workbook (WB)
var xlWS = (Excel.Worksheet)xlApp.ActiveSheet; // Reference the active worksheet (WS)
xlWS.Name = "Exported Student"; // Name the worksheet
// Add Header fields to Excel [row, column]
var r = 1;
xlWS.Cells[r, 1] = "Name";
xlWS.Cells[r, 2] = "Score";
// Copy data from StudentList to Excel
foreach (Student student in studentList)
{
r++;
xlWS.Cells[r, 1] = student.Name;
xlWS.Cells[r, 2] = student.Score;
}
}
This will automatically export your studentList to an excel sheet. There wasn't a need for the ListToDataTable class.

Excel Found unreadable content -POI XSSFWorkbook setcellvalue

I am trying to setcellvalue for xlsx file , Program works fine with no error , but while opening the xlsx file it throws an error saying Excel Found unreadable content
public boolean setCellData(String sheetName,String colName,int rowNum, String data){
try{
fis = new FileInputStream(path);
workbook = new XSSFWorkbook(path);
if(rowNum<=0)
return false;
int index = workbook.getSheetIndex(sheetName);
int colNum=-1;
if(index==-1)
return false;
sheet = workbook.getSheetAt(index);
row=sheet.getRow(0);
for(int i=0;i<row.getLastCellNum();i++){
//System.out.println(row.getCell(i).getStringCellValue().trim());
if(row.getCell(i).getStringCellValue().trim().equals(colName))
colNum=i;
}
if(colNum==-1)
return false;
sheet.autoSizeColumn(colNum);
row = sheet.getRow(rowNum-1);
if (row == null)
row = sheet.createRow(rowNum-1);
cell = row.getCell(colNum);
if (cell == null)
cell = row.createCell(colNum);
// cell style
//CellStyle cs = workbook.createCellStyle();
//cs.setWrapText(true);
//cell.setCellStyle(cs);
cell.setCellValue(data);
fileOut = new FileOutputStream(path);
workbook.write(fileOut);
fileOut.close();
}
catch(Exception e){
e.printStackTrace();
return false;
}
return true;
}
You have initialized FileInputStream, but not used that. Please replace
fis = new FileInputStream(path);
workbook = new XSSFWorkbook(path);
with
fis = new FileInputStream(path);
workbook = new XSSFWorkbook(fis);
this works on my end and not showing any error.

Resources