转载请注明来源-作者@loongshawn:
http://blog.csdn.net/loongshawn/article/details/51996801
1、背景说明
业务中有时候会碰到利用java 处理excel文件(生成、下载、上传),通常生成一个excel文件会把它写入到机器的一个临时路径,但有时候完全没必要把它存下来,只需要在内存中把这个文件转为输入流,至于后面怎么处理都行。
2、所需依赖包
Java中创建excel文件利用到了以下两个依赖包poi-3.14.jar、poi-ooxml-3.14.jar:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
3、excel文件处理方式
3.1、方式一:保存为本地文件
通常在创建XSSFWorkbook后,可以通过以下这种方式来存储该表格,即利用FileOutputStream把文件写入其中,这个FileOutputStream指定了文件系统存在的路径:
XSSFWorkbook wb =
new
XSSFWorkbook();
Sheet sheet = wb.createSheet(
"Sheet0"
);
filePath =
"d://"
+filename+
"tongji.xls"
;
try
{
FileOutputStream out =
new
FileOutputStream(filepath);
wb.write(out);
out.close();
result_return =
true
;
logger.info(
"ExcelService createExcelTable Result: "
+ result_return);
}
catch
(IOException e) {
result_return =
false
;
logger.error(
"ExcelService createExcelTable Error: "
+ e);
3.2、方式二:保存为输入流
将XSSFWorkbook对象保存为输入流时,利用到了ByteArrayOutputStream来做缓存,先将文件写入其中,然后将其转为字节数组,最后利用ByteArrayInputStream转为输入流,供后续使用。
XSSFWorkbook wb =
new
XSSFWorkbook();
Sheet sheet = wb.createSheet(
"Sheet0"
);
ByteArrayInputStream in =
null
;
try
{
ByteArrayOutputStream os =
new
ByteArrayOutputStream();
wb.write(os);
byte
[] b = os.toByteArray();
in =
new
ByteArrayInputStream(b);
os.close();
}
catch
(IOException e) {
logger.error(
"ExcelUtils getExcelFile error:{}"
,e.toString());
return
null
;
return
in;
3.3、FileOutputStream与ByteArrayOutputStream之间的区别
要了解FileOutputStream与ByteArrayOutputStream之间的区别,需要查阅
java API
。
先来看看API中对FileOutputStream的描述:
FileOutputStream需要指定具体文件或者文件描述路径,才能完成数据写入,可以把它理解为一个管道,管道不能存数据。
再来看看API中对ByteArrayOutputStream的描述:
ByteArrayOutputStream定义了一个ByteArray的输出流,能够往里面写入数据,其实就是内存中的一个对象,同时实现了OutputStream。可以把它理解为一个自带管道的容器,容器能直接存数据。
4、上传OSS
接收到了excel文件的输入流后,利用OSS接口实现上传。
public static String uploadOSS(ByteArrayInputStream input,String issuenumber){
String url = null;
if(input != null){
String fileName = issuenumber + "_工单详情.xlsx";
try {
HttpPost httpPost = new HttpPost("http://127.0.0.1/api/attachment/oss");
httpPost.addHeader("key","12345");
httpPost.addHeader("user","xiaomen");
httpPost.addHeader("method","FeedbackSelect");
httpPost.addHeader("filename",new String(fileName.getBytes("UTF-8"),"ISO-8859-1"));
httpPost.addHeader("type","01");
InputStreamEntity reqEntity = new InputStreamEntity(input);
httpPost.setEntity(reqEntity);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
if(responseEntity != null){
InputStream inputStream = responseEntity.getContent();
String data = convertStreamToString(inputStream);
logger.info("FileUpload2OSS uploadOSS data:{}",data);
JSONObject json = JSON.parseObject(data);
if(json.containsKey("statusCode")){
int statusCode = json.getIntValue("statusCode");
if(statusCode == 0){
JSONArray array = json.getJSONArray("responseData");
JSONObject j = array.getJSONObject(0);
url = j.getString("attachment");
input.close();
} catch (UnsupportedEncodingException e) {
logger.error("FileUpload2OSS uploadOSS UnsupportedEncodingException:{}",e.toString());
return url;
} catch (ClientProtocolException e) {
logger.error("FileUpload2OSS uploadOSS ClientProtocolException:{}",e.toString());
return url;
} catch (IOException e) {
logger.error("FileUpload2OSS uploadOSS IOException:{}",e.toString());
return url;
return url;
针对具体业务可以自由选择处理方式。如果无需存储文件至系统,则考虑第二种方式。
在我自己的业务中,使用了第二种方式,无需将生成的excel存在服务器即可完成上传线上OSS。
结果样例:http://url.na
由于需求。。
使用了ByteArrayOutputStream和ByteArrayInputStream类.
将XSSFWorkbook 写入ByteArrayOutputStream.然后用ByteArrayOutputStream来转换为字节流.然后再将字节流转换为ByteArrayInputStream …至此,我们就在内存中将excel转换成了输入流…
话不多说,上代码:
//wb ...
* @param multipartFile multipartFile
* @return InputStream
* @throws IOException IOException
public static InputStream parseInputStream(MultipartFile multip
public static InputStream workbookConvertorStream(SXSSFWorkbook workbook) {
InputStream in = null;
//临时缓冲区
ByteArrayOutputStream out = new ByteArrayOutputStream();
package com.jd.ibdreport.service.approta;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.
InputStream is = new ByteArrayInputStream(HSSFWorkbook.getBytes());
获取输入流后上传服务器。文件是上传成功,但是文件下载后打开会提示文件已损坏。
正确的解决方法(红色涂改...
君且信步登天路,莫惜玩泥孩童时!对于一个爱写代码的人来说,坚持写代码是最好的诠释。我会努力写代码的,也希望我的分享能给你们带来帮助,我觉得这就是我努力的意义,不仅你们收获到了知识,我也看到了自已的进步!
03-30
1. 使用Apache POI库
Apache POI是一个Java库,可以处理Microsoft Office格式的文件,包括Excel。如果你的实体类是基于JavaBean规范的,那么可以使用Apache POI来导出Excel文件。
首先,你需要将实体类的属性与Excel表格中的列一一对应,定义一个数据模型。然后,使用Apache POI的API将数据写入Excel文件中。
以下是一个基于Apache POI的示例代码:
```java
public void exportExcel(List<Book> bookList, OutputStream outputStream) {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Book List");
// 创建表头
HSSFRow headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("Book ID");
headerRow.createCell(1).setCellValue("Title");
headerRow.createCell(2).setCellValue("Author");
headerRow.createCell(3).setCellValue("Price");
// 填充数据
int rowNum = 1;
for (Book book : bookList) {
HSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(book.getId());
row.createCell(1).setCellValue(book.getTitle());
row.createCell(2).setCellValue(book.getAuthor());
row.createCell(3).setCellValue(book.getPrice());
// 输出Excel文件
try {
workbook.write(outputStream);
} catch (IOException e) {
e.printStackTrace();
2. 使用EasyExcel库
EasyExcel是一个基于阿里巴巴开发的Java库,可以方便地导入和导出Excel文件。如果你的实体类是基于Java Bean规范的,那么可以使用EasyExcel来导出Excel文件。
以下是一个基于EasyExcel的示例代码:
```java
public void exportExcel(List<Book> bookList, OutputStream outputStream) {
List<BookDTO> bookDTOList = bookList.stream().map(BookDTO::new).collect(Collectors.toList());
ExcelWriter excelWriter = EasyExcel.write(outputStream, BookDTO.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("Book List").build();
excelWriter.write(bookDTOList, writeSheet);
excelWriter.finish();
在这个示例代码中,我们先将Book实体类转换为BookDTO数据传输对象,然后使用EasyExcel的API将数据写入Excel文件中。注意,EasyExcel的API比Apache POI更加简洁易用,但是可能会比较耗费内存。