Extension not added on excel generation (APACHE POI) - export-to-excel

I am generating an excel sheet using Apache POI in my spring mvc3 project. The file is generated without .xls extension. If I rename the same file with .xls manually the data is generated fine. Here is the snippet of my code::
#RequestMapping(value = "/download/")
public void downloadMerchantMiniStatement(final HttpServletResponse response,
#RequestParam(value = "fromDate", required = true) String fromDate,
#RequestParam(value = "toDate", required = true) String toDate,
#RequestParam(value = "status", required = false) String status
) throws IOException {
String fileName = STATEMENT_REPORT_" + getDateString(new Date()) + ".xls";
List<TransactionDTO> transactionDtos = excelService.getTransactionsForExcel(Status, DateUtil.convertStringToDate(fromDate), DateUtil.convertStringToDate(toDate));
ByteArrayOutputStream excel = getExcelStatement(transactionDtos, fromDate, toDate, status);
excel.writeTo(response.getOutputStream());
response.setContentType("application/excel");
response.setHeader("Expires:", "0");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.getOutputStream().flush();
response.getOutputStream().close();
}

Finally got the solution, the code response.setContentType("application/excel");
needed to be replaced with response.setContentType("application/vnd.ms-excel");
That gives a standard format output.

Related

How to use MockMVC test the controller which use org.apache.commons.fileupload?

My Controller use " org.apache.commons.fileupload " realized the file UPload.
see it:
#PostMapping("/upload")
public String upload2(HttpServletRequest request) throws Exception {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
boolean uploaded = false;
while (iter.hasNext() && !uploaded) {
FileItemStream item = iter.next();
if (item.isFormField()) {
item.openStream().close();
} else {
String fieldName = item.getFieldName();
if (!"file".equals(fieldName)) {
item.openStream().close();
} else {
InputStream stream = item.openStream();
// dosomething here.
uploaded = true;
}
}
}
if (uploaded) {
return "ok";
} else {
throw new BaseResponseException(HttpStatus.BAD_REQUEST, "400", "no file field or data file is empty.");
}
}
and my MockMvc code is
public void upload() throws Exception {
File file = new File("/Users/jianxiaowen/Documents/a.txt");
MockMultipartFile multipartFile = new MockMultipartFile("file", new FileInputStream(file));
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "----WebKitFormBoundaryaDEFKSFMY18ehkjt");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(baseUrl+"/upload")
.content(multipartFile.getBytes())
.contentType(mediaType)
.header(Origin,OriginValue)
.cookie(cookie))
.andReturn();
logResult(mvcResult);
}
my controller is right , it has successed in my web project,
but I want to test it use MvcMock, it has some mistake, see :
can someOne can help me?
"status":"400","msg":"no file field or data file is empty.","data":null
I don't know why it says my file is empty.
my English is poor, thank you very much if someone can help me.
The MockMvc can be used for integration testing for controllers using Apache Commons Fileupload too!
Import the org.apache.httpcomponents:httpmime into your pom.xml or gradle.properties
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
</dependency>
Update the code to use MultipartEntityBuilder to build the multipart request on the client, and then serialize the entity into bytes, which is then set in the request content
public void upload() throws Exception {
File file = new File("/Users/jianxiaowen/Documents/a.txt");
String boundary = "----WebKitFormBoundaryaDEFKSFMY18ehkjt";
// create 'Content-Type' header for multipart along with boundary
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", boundary); // set boundary in the header
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
// create a multipart entity builder, and add parts (file/form data)
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
HttpEntity multipartEntity = MultipartEntityBuilder.create()
.addPart("file", new FileBody(file, ContentType.create("text/plain"), file.getName())) // add file
// .addTextBody("param1", "value1") // optionally add form data
.setBoundary(boundary) // set boundary to be used
.build();
multipartEntity.writeTo(outputStream); // or getContent() to get content stream
byte[] content = outputStream.toByteArray(); // serialize the content to bytes
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post(baseUrl + "/upload")
.contentType(mediaType)
.content(content) // finally set the content
.header(Origin,OriginValue)
.cookie(cookie)
).andReturn();
logResult(mvcResult);
}
Can you try the below?
mockMvc.perform(
MockMvcRequestBuilders.multipart(baseUrl+"/upload")
.file(multiPartFile)
).andReturn();
Update:
You need to update the controller to handle the MultipartFile:
#PostMapping("/upload")
public String upload2(#RequestParam(name="nameOfRequestParamWhichContainsFileData")
MultipartFile uploadedFile, HttpServletRequest request) throws Exception {
//the uploaded file gets copied to uploadedFile object.
}
You need not use another library for managing file uploads. You can use the file upload capabilities provided by Spring MVC.

SpringBoot base64 pdf downloading

When user makes a get request this should download a pdf file, so far I am getting base64 of the pdf file but I don't know how to download. Can someone help me out?
#ResponseBody
#GetMapping("/download/pdf/{uuid}/{userid}")
public String downloadPdf (#PathVariable String uuid,#PathVariable String userid, Model model) {
JSONObject jsonObject = RequestHelper.getResponse("pdf", uuid);
JSONArray d =(JSONArray) jsonObject.get("data");
String str = (String) d.get(0);
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
// I have base64 pdf how can I start downloading this pdf
return("file downloaded");
}
Add Rest Controller to spring boot project and below method to download pdf file from base64 content.
Assign the pdf base64 string to content variable.
#GetMapping(value = "/donw1")
public ResponseEntity<Resource> donw1() {
logger.info("Start the file processing");
String content = "<<Add_pdf_base64 content here>>";
byte[] decoder = Base64.getDecoder().decode(content);
InputStream is = new ByteArrayInputStream(decoder);
InputStreamResource resource = new InputStreamResource(is);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
ContentDisposition disposition = ContentDisposition.attachment().filename("textdown.pdf").build();
headers.setContentDisposition(disposition);
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}

Stream data in response for Spring MVC 4.3 Using Java 8, Tomcat 7

Below is the piece of code that causes OutOfMemory issue when I run my xyz.war in tomcat 7 with Java 8.
In Below code I am creating a CSV response of the data that was fetched from MongoDB via cursor.
#RequestMapping(value = "/elements/{elementname}/records", method = RequestMethod.GET)
public ModelAndView getAllRecords(
HttpServletRequest request, HttpServletResponse response,
#RequestParam(value = "customerid", required = true) long customerId,
#RequestParam(value = "userid", required = true) long userId,
#RequestParam(value = "query", required = false) String query,
throws Exception {
Map < String, Object > model = new HashMap < String, Object > ();
JsonObject records = elementService.searchRecords(query);
ModelAndViewData msvd = elementService.commonRestService
.getModelAndView("dataObject", "streamingView");
return new ModelAndView(msvd.getViewName(), handleCsvReportTypeRequest(records, customerId, userId));
}
public Map < String, Object > handleCsvReportTypeRequest(JsonObject records,
String elementName, long customerId, long userId) throws Exception {
StringBuffer csvData = new StringBuffer();
// create csv data
ModelAndViewData modelAndStreamingViewData = commonRestService.getModelAndView(
"dataObject", "streamingView");
byte[] byteArray = String.valueOf(csvData).getBytes();
InputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
model.put(modelAndStreamingViewData.getModelAttributeName(), byteArrayInputStream);
model.put(DownloadConstants.CONTENT_TYPE, DownloadConstants.CSV_CONTENT_TYPE);
model.put(DownloadConstants.FILENAME, "XYZ.csv");
model.put(DownloadConstants.LAST_MODIFIED, new Date(System.currentTimeMillis()));
model.put(DownloadConstants.CONTENT_LENGTH, Integer.valueOf(byteArray.length));
return model;
}
How can I stream CSV data back to the user without creating a huge data in memory and then passing to the user?
Use a Buffered read and write the response in HttpResponse object.
Try this way:
Spring MVC : large files for download, OutOfMemoryException

Encoding for downloaded files in Spring

I want to create a controller which will sent to client a CSV file, and I created the next controller:
#ResponseStatus(value = HttpStatus.OK)
#RequestMapping(value = "/csv", method = RequestMethod.GET)
public ResponseEntity downloadCsvAllInvoiceTransactionsByFilter(
#PageableDefault(direction = DESC, sort = "invoiceDate", size = 30) Pageable pageRequest) throws IOException {
String someVariable = "Some text";
byte[] out = someVariable.getBytes(Charset.forName("UTF-8"));
HttpHeaders responseHeaders = new HttpHeaders();
LOGGER.info(new String(out));
responseHeaders.add("content-disposition", "attachment; filename=transactions.csv" );
responseHeaders.add("Content-Type","text/csv; charset=utf-8");
return new ResponseEntity<>(out,responseHeaders,HttpStatus.OK);
}
Logger is displaying the correct string:
Some text
but in downloaded file there is another one
U29tZSB0ZXh0
How can I fix this?
Body of ResponseEntity goes through a message converter before it gets sent. The choice of the particular converter depends on class of the body and response and request headers.
I tried to reproduce the issue with your code snippet and got expected text in csv file. So I assume that you got a message converter registered that converts byte arrays the way you observe.
You can debug AbstractMessageConverterMethodProcessor#writeWithMessageConverters and see which converter is chosen and why.

read data from MultipartFile which has csv uploaded from browser

May be I am doing it worng by using MultipartFile upload feature.
I have to read data from csv file which will be chosen by the client through the browser. I used MultipartFile to upload file. The file is coming to the controller but now I am unable to read csv data from it. Please guide the best way to do it or help me read csv data from MultipartFile.
The jsp has
<form method="POST" action="uploadFile" enctype="multipart/form-data">
File to upload: <input type="file" name="file"> <input
type="submit" value="Upload"> Press here to upload the
file!
</form>
The controller has
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadFileHandler(#RequestParam("file") MultipartFile file) {
Thanks.
I used a buffer to read line by line and get from multipart the inputstream. Maybe is more code, but I find helpful read text file by lines.
BufferedReader br;
List<String> result = new ArrayList<>();
try {
String line;
InputStream is = multipart.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
result.add(line);
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
I figured out a workaround. I converted the file to bytes and then converted the bytes to String. From String I applied string.split() to get what I wanted out of the file.
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadFileHandler(#RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
String completeData = new String(bytes);
String[] rows = completeData.split("#");
String[] columns = rows[0].split(",");
The best solution that I found was
#PostMapping(value="/csv")
public ResponseEntity<Void> processUpload(#RequestParam MultipartFile file) {
BufferedReader fileReader = new BufferedReader(new
InputStreamReader(file.getInputStream(), "UTF-8"));
CSVParser csvParser = new CSVParser(fileReader, CSVFormat.DEFAULT);
Iterable<CSVRecord> csvRecords = csvParser.getRecords();
for (CSVRecord csvRecord : csvRecords) {
System.out.println(csvRecord);
}
...
This is an adaptative solution from https://bezkoder.com/spring-boot-upload-csv-file/

Resources