建议描述 现有需求,数据导出到Excel,并且上传到OSS,进行存储以待用户选择合适时间进行下载
那么遇到的问题就是,没有找到合适的方法,调用API上传到OSS
所以请提供一个这样的最佳方案的代码
建议描述 现有需求,数据导出到Excel,并且上传到OSS,进行存储以待用户选择合适时间进行下载
那么遇到的问题就是,没有找到合适的方法,调用API上传到OSS
所以请提供一个这样的最佳方案的代码
有两种方案:
请问如何将导出的文件导出至指定位置,或者说直接将ExcelWriter这个输出流对接到oss(直接导入oss文件服务器)
请问如何将导出的文件导出至指定位置,或者说直接将ExcelWriter这个输出流对接到oss(直接导入oss文件服务器)
第一种:把oss挂载到服务器,比如挂载到 /yourOssMountPath
目录下,那么,输出的代码就是:
//这里只是提示是一个文件路径
File outputFile = new File("/yourOssMountPath/yourDir/yourExcelFileName.xlsx");
EasyExcel.write(outputFile, DemoData.class).sheet("模板").doWrite(data());
第二种的话,流转换一下就好了
//这里只是输出到内存中,大文件不要这么做
ByteArrayOutputStream bos = new ByteArrayOutputStream();
EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data());
//ossClient请参照oss的SDK,这里以aliyunOss为例
ossClient.putObject("<yourBucketName>", "<yourExcelFileName>", new ByteArrayInputStream(bos.toByteArray()));
谢谢大佬,但是第二种方法 会报异常 SaveContextServletOutputStream转换为java.io.ByteArrayOutputStream 而且用的导出是阿里云ExcelWriter这个类
谢谢大佬,但是第二种方法 会报异常 SaveContextServletOutputStream转换为java.io.ByteArrayOutputStream 而且用的导出是阿里云ExcelWriter这个类
我测试了输出到ByteArrayOutputStream没有问题2.1.3
,没有看到报错
ExcelWriter这个类不能直接新建,要通过EasyExcel这个工厂类来创建
大佬,可是 response 里面拿到的是ServletOutputStream,转换ByteArrayOutputStream, 会报错的。。。
大佬,可是 response 里面拿到的是ServletOutputStream,转换ByteArrayOutputStream, 会报错的。。。
不兼容类型强转当然会报错……
如果你只是web应用不需要输出到oss或者response是oss SDK的响应的话
EasyExcel.write(response.getOutputStream(), DemoData.class).sheet("模板").doWrite(data());
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这里是阿里云官方oss的demo简单上传oss的简单完整demo
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";
// <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
String objectName = "<yourObjectName>";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
//这里只是输出到内存中,大文件不要这么做
ByteArrayOutputStream bos = new ByteArrayOutputStream();
EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data());
//ossClient请参照oss的SDK,这里以aliyunOss为例
ossClient.putObject("<yourBucketName>", "<yourDir>/<yourExcelFileName>.xlsx", new ByteArrayInputStream(bos.toByteArray()));
// 关闭OSSClient。
ossClient.shutdown();
这个文件就被放到http://<yourBucketName>.oss-cn-hangzhou.aliyuncs.com/<yourDir>/<yourExcelFileName>.xlsx
把这个路径发送给前端,前端访问这个路径就可以获取生成的excel文件,
或者利用OSS SDK/HTTP读取这个文件输出到response.getOutputStream()
,就可以做文件下载了
问题已解决,感谢大佬!
大佬,EasyExcel的背景颜色设置可以支持RBG吗???
RGB #FF0000
RGB #FF0000
优先使用百度搜索解决方案比较好 目前easyExcel使用的时POI写入,POI设置背景颜色的方法是
style.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
IndexedColors
的枚举数量是有限的
如果想支持自定义RGB的话,请查看这篇文章
//自定义RGB HSSFPalette customPalette = workbook.getCustomPalette(); //这里的setColorAtIndex方法需要的参数是(short index, byte red, byte green, byte blue) //这里的short我们直接用Java给我们提供的,我看有些人用的是自定义的short那个会有问题的 customPalette.setColorAtIndex(IndexedColors.LIGHT_YELLOW.getIndex(), (byte) 255, (byte) 230, (byte) 153);
但是这样会覆盖掉原先的颜色,自行取舍
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这里是阿里云官方oss的demo简单上传oss的简单完整demo
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = "<yourObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。 //这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourDir>/<yourExcelFileName>.xlsx", new ByteArrayInputStream(bos.toByteArray())); // 关闭OSSClient。 ossClient.shutdown();
这个文件就被放到
http://<yourBucketName>.oss-cn-hangzhou.aliyuncs.com/<yourDir>/<yourExcelFileName>.xlsx
把这个路径发送给前端,前端访问这个路径就可以获取生成的excel文件, 或者利用OSS SDK/HTTP读取这个文件输出到response.getOutputStream()
,就可以做文件下载了
怎么定义这个文件的大小,多大才算大,50M 以内?
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这里是阿里云官方oss的demo简单上传oss的简单完整demo
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = "<yourObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。 //这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourDir>/<yourExcelFileName>.xlsx", new ByteArrayInputStream(bos.toByteArray())); // 关闭OSSClient。 ossClient.shutdown();
这个文件就被放到
http://<yourBucketName>.oss-cn-hangzhou.aliyuncs.com/<yourDir>/<yourExcelFileName>.xlsx
把这个路径发送给前端,前端访问这个路径就可以获取生成的excel文件, 或者利用OSS SDK/HTTP读取这个文件输出到response.getOutputStream()
,就可以做文件下载了怎么定义这个文件的大小,多大才算大,50M 以内?
根据你业务来评估的,如果你导出的数据是固定行数,或者不会超出一定限度的话,直接输出就可以,如果是根据业务量增长的话,最好是异步处理。
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这里是阿里云官方oss的demo简单上传oss的简单完整demo
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = "<yourObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。 //这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourDir>/<yourExcelFileName>.xlsx", new ByteArrayInputStream(bos.toByteArray())); // 关闭OSSClient。 ossClient.shutdown();
这个文件就被放到
http://<yourBucketName>.oss-cn-hangzhou.aliyuncs.com/<yourDir>/<yourExcelFileName>.xlsx
把这个路径发送给前端,前端访问这个路径就可以获取生成的excel文件, 或者利用OSS SDK/HTTP读取这个文件输出到response.getOutputStream()
,就可以做文件下载了怎么定义这个文件的大小,多大才算大,50M 以内?
根据你业务来评估的,如果你导出的数据是固定行数,或者不会超出一定限度的话,直接输出就可以,如果是根据业务量增长的话,最好是异步处理。
目前导出 30W+,同步输出大概 4 分钟左右,文件大小 40M左右。所以现在考虑异步上传到 OSS,想采取输出流的方案,但是看到你的 demo 代码有一句注释,"//这里只是输出到内存中,大文件不要这么做",只是好奇衡量大文件的标准是啥?看jvm 设置的内存大小占比吗?
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这里是阿里云官方oss的demo简单上传oss的简单完整demo
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = "<yourObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。 //这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourDir>/<yourExcelFileName>.xlsx", new ByteArrayInputStream(bos.toByteArray())); // 关闭OSSClient。 ossClient.shutdown();
这个文件就被放到
http://<yourBucketName>.oss-cn-hangzhou.aliyuncs.com/<yourDir>/<yourExcelFileName>.xlsx
把这个路径发送给前端,前端访问这个路径就可以获取生成的excel文件, 或者利用OSS SDK/HTTP读取这个文件输出到response.getOutputStream()
,就可以做文件下载了怎么定义这个文件的大小,多大才算大,50M 以内?
根据你业务来评估的,如果你导出的数据是固定行数,或者不会超出一定限度的话,直接输出就可以,如果是根据业务量增长的话,最好是异步处理。
目前导出 30W+,同步输出大概 4 分钟左右,文件大小 40M左右。所以现在考虑异步上传到 OSS,想采取输出流的方案,但是看到你的 demo 代码有一句注释,"//这里只是输出到内存中,大文件不要这么做",只是好奇衡量大文件的标准是啥?看jvm 设置的内存大小占比吗?
bos输出的流会存储在内存里,内存紧张的时候这种操作可能会引起频繁GC的……,4分钟的确应该异步处理的
这个需求是,用户点导出的时候,给这个导出的文件(未生成),给放到Oss里面去, 大佬可以教下我怎么做吗? (原来有个想法是,先生成到linux某个文件夹,然后在读取这个文件,存入oss后再删掉,但是发现好像导出没法指定路径)
这里是阿里云官方oss的demo简单上传oss的简单完整demo
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = "<yourObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。 //这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourDir>/<yourExcelFileName>.xlsx", new ByteArrayInputStream(bos.toByteArray())); // 关闭OSSClient。 ossClient.shutdown();
这个文件就被放到
http://<yourBucketName>.oss-cn-hangzhou.aliyuncs.com/<yourDir>/<yourExcelFileName>.xlsx
把这个路径发送给前端,前端访问这个路径就可以获取生成的excel文件, 或者利用OSS SDK/HTTP读取这个文件输出到response.getOutputStream()
,就可以做文件下载了怎么定义这个文件的大小,多大才算大,50M 以内?
根据你业务来评估的,如果你导出的数据是固定行数,或者不会超出一定限度的话,直接输出就可以,如果是根据业务量增长的话,最好是异步处理。
目前导出 30W+,同步输出大概 4 分钟左右,文件大小 40M左右。所以现在考虑异步上传到 OSS,想采取输出流的方案,但是看到你的 demo 代码有一句注释,"//这里只是输出到内存中,大文件不要这么做",只是好奇衡量大文件的标准是啥?看jvm 设置的内存大小占比吗?
bos输出的流会存储在内存里,内存紧张的时候这种操作可能会引起频繁GC的……,4分钟的确应该异步处理的 那这样的话先临时写到服务器本地,再上传文件流,这样应该可以避免GC 吧?而且上传成功后如何通知前端获取这个文件 url?有什么比较好的方式,提供一个接口让前端轮询?
那这样的话先临时写到服务器本地,再上传文件流,这样应该可以避免GC 吧?而且上传成功后如何通知前端获取这个文件 url?有什么比较好的方式,提供一个接口让前端轮询?
把bos换成FileOutputStream就可以了,文件找个临时路径,生成结束之后删除这个文件,至于url请参考上面的阿里云是oss实现,url写到异步任务的列表里即可
那这样的话先临时写到服务器本地,再上传文件流,这样应该可以避免GC 吧?而且上传成功后如何通知前端获取这个文件 url?有什么比较好的方式,提供一个接口让前端轮询?
把bos换成FileOutputStream就可以了,文件找个临时路径,生成结束之后删除这个文件,至于url请参考上面的阿里云是oss实现,url写到异步任务的列表里即可
你好,我也碰到这个问题了,除了写临时文件的方案,还有更好解决办法吗? 写磁盘的话又多了两次IO操作,处理时间和系统资源占用上都不是很好的办法。
那这样的话先临时写到服务器本地,再上传文件流,这样应该可以避免GC 吧?而且上传成功后如何通知前端获取这个文件 url?有什么比较好的方式,提供一个接口让前端轮询?
把bos换成FileOutputStream就可以了,文件找个临时路径,生成结束之后删除这个文件,至于url请参考上面的阿里云是oss实现,url写到异步任务的列表里即可
你好,我也碰到这个问题了,除了写临时文件的方案,还有更好解决办法吗? 写磁盘的话又多了两次IO操作,处理时间和系统资源占用上都不是很好的办法。
还有一种方案就是@pdkst 说的:挂载oss到本地(linux)这样和本地写文件一样,就避免了两次 IO 操作
请问如何将导出的文件导出至指定位置,或者说直接将ExcelWriter这个输出流对接到oss(直接导入oss文件服务器)
第一种:把oss挂载到服务器,比如挂载到
/yourOssMountPath
目录下,那么,输出的代码就是://这里只是提示是一个文件路径 File outputFile = new File("/yourOssMountPath/yourDir/yourExcelFileName.xlsx"); EasyExcel.write(outputFile, DemoData.class).sheet("模板").doWrite(data());
第二种的话,流转换一下就好了
//这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourExcelFileName>", new ByteArrayInputStream(bos.toByteArray()));
请问大佬我使用第二种输出流的方式创建excel,但是用下面这种写法,生成的文件打不开,我debug显示输出流没有写入值,不知道有没有遇到这种情况?
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ExcelWriter excelWriter = EasyExcel.write(baos,Demo.class).build();
WriteSheet allSheet = EasyExcel.writerSheet(0, "总体概览").build();
excelWriter.write(data(), allSheet);
请问如何将导出的文件导出至指定位置,或者说直接将ExcelWriter这个输出流对接到oss(直接导入oss文件服务器)
第一种:把oss挂载到服务器,比如挂载到
/yourOssMountPath
目录下,那么,输出的代码就是://这里只是提示是一个文件路径 File outputFile = new File("/yourOssMountPath/yourDir/yourExcelFileName.xlsx"); EasyExcel.write(outputFile, DemoData.class).sheet("模板").doWrite(data());
第二种的话,流转换一下就好了
//这里只是输出到内存中,大文件不要这么做 ByteArrayOutputStream bos = new ByteArrayOutputStream(); EasyExcel.write(bos, DemoData.class).sheet("模板").doWrite(data()); //ossClient请参照oss的SDK,这里以aliyunOss为例 ossClient.putObject("<yourBucketName>", "<yourExcelFileName>", new ByteArrayInputStream(bos.toByteArray()));
请问大佬我使用第二种输出流的方式创建excel,但是用下面这种写法,生成的文件打不开,我debug显示输出流没有写入值,不知道有没有遇到这种情况?
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ExcelWriter excelWriter = EasyExcel.write(baos,Demo.class).build(); WriteSheet allSheet = EasyExcel.writerSheet(0, "总体概览").build(); excelWriter.write(data(), allSheet);
一般打不开都是数据为null
,试试转换null
为emptyList