思路:excel的读写借助于poi框架,在写入远程的时候,是不能直接写入的,本博主将传入的文件再次拉下来写到项目临时文件中,然后,在临时文件中写入,然后,以同样的名称路径覆盖掉远程的就可以了,稍微有点绕了,从远端获取文件,需要通过流来写到项目临时文件中,具体见下方代码,代码中有部分业务删减,该代码是在工作中运行通过的。模板是我们自己制定的,所以只适合已有模板。

文件工具类及方法:

 package com.XXXX.XXXXX.utils;

 import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils; import com.sun.javafx.scene.control.skin.TreeTableRowSkin;
import com.xxx.cloud.common.utils.DateFormatUtil;
import com.xxx.cloud.common.utils.StringUtil; public class ReadExcelUtil { private static final String EXCEL_XLS = ".xls";
private static final String EXCEL_XLSX = ".xlsx"; /**
*读取excel数据
* @throws Exception
*
*/
public static List<List<String>> readExcelInfo(String url) throws Exception{
// 支持excel2003、2007
File excelFile = new File(url);//创建excel文件对象
InputStream is = new FileInputStream(excelFile);//创建输入流对象
checkExcelVaild(excelFile);
Workbook workbook = getWorkBook(is, excelFile);
// Workbook workbook = WorkbookFactory.create(is);//同时支持2003、2007、2010
// 获取Sheet数量
int sheetNum = workbook.getNumberOfSheets();
sheetNum = 1;//限制模板只在一个工作簿上操作
// 创建二维数组保存所有读取到的行列数据,外层存行数据,内层存单元格数据
List<List<String>> dataList = new ArrayList<List<String>>();
// 遍历工作簿中的sheet,第一层循环所有sheet表
for(int index = 0;index<sheetNum;index++){
Sheet sheet = workbook.getSheetAt(index);
if(sheet==null){
continue;
}
// 如果当前行没有数据跳出循环,第二层循环单sheet表中所有行
for(int rowIndex=0;rowIndex<=sheet.getLastRowNum();rowIndex++){
System.out.println(sheet.getLastRowNum()+"====");
Row row = sheet.getRow(rowIndex);
if(row==null){
continue;
}
// 遍历每一行的每一列,第三层循环行中所有单元格
List<String> cellList = new ArrayList<String>();
for(int cellIndex=0;cellIndex<row.getLastCellNum();cellIndex++){
Cell cell = row.getCell(cellIndex);
System.out.println(cellIndex);
cellList.add(getCellValue(cell));
}
dataList.add(cellList);
} }
is.close();
return dataList;
}
/**
*获取单元格的数据,暂时不支持公式
*
*
*/
public static String getCellValue(Cell cell){
CellType cellType = cell.getCellTypeEnum();
if(cellType==null){
return null;
}
String cellValue = "";
if(cell==null || cell.toString().trim().equals("")){
return null;
} if(cellType==CellType.STRING){
cellValue = cell.getStringCellValue().trim();
return cellValue = StringUtil.isEmpty(cellValue)?"":cellValue;
}
if(cellType==CellType.NUMERIC){
if (HSSFDateUtil.isCellDateFormatted(cell)) { //判断日期类型
cellValue = DateFormatUtil.formatDurationYMD(cell.getDateCellValue().getTime());
} else { //否
cellValue = new DecimalFormat("#.######").format(cell.getNumericCellValue());
}
return cellValue;
}
if(cellType==CellType.BOOLEAN){
cellValue = String.valueOf(cell.getBooleanCellValue());
return cellValue;
}
return null; }
/**
*判断excel的版本,并根据文件流数据获取workbook
* @throws IOException
*
*/
public static Workbook getWorkBook(InputStream is,File file) throws Exception{ Workbook workbook = null;
if(file.getName().endsWith(EXCEL_XLS)){
workbook = new HSSFWorkbook(is);
}else if(file.getName().endsWith(EXCEL_XLSX)){
workbook = new XSSFWorkbook(is);
} return workbook;
}
/**
*校验文件是否为excel
* @throws Exception
*
*
*/
public static void checkExcelVaild(File file) throws Exception {
String message = "该文件是EXCEL文件!";
if(!file.exists()){
message = "文件不存在!";
throw new Exception(message);
}
if(!file.isFile()||((!file.getName().endsWith(EXCEL_XLS)&&!file.getName().endsWith(EXCEL_XLSX)))){
message = "文件不是Excel";
throw new Exception(message);
}
}
/**
*校验上传的excel模板是否正确
*
*
*
*/
public static boolean checkExcelTemplate(String url){
try {
List<List<String>> list = ReadExcelUtil.readExcelInfo(url);
for(int i=0;i<list.size();i++){
if(i==0){
if(!list.get(i).get(0).trim().equals("公司ID")||!list.get(i).get(1).trim().equals("产品ID")||!list.get(0).get(2).trim().equals("设备类型")
||!list.get(i).get(3).trim().equals("设备型号")||!list.get(i).get(4).trim().equals("设备名称")){
return false;
}
}
if(i==2){
if(!list.get(i).get(0).trim().equals("设备ID")||!list.get(i).get(1).trim().equals("结果")){
return false;
}
}
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true; }
/**
* 将反馈结果写入excel中
* */
public static void writeExcelResult(String url,List<Integer> result) throws Exception{
// 支持excel2003、2007
File excelFile = new File(url);//创建excel文件对象
InputStream is = new FileInputStream(excelFile);//创建输入流对象
checkExcelVaild(excelFile);
Workbook workbook = getWorkBook(is, excelFile);
// Workbook workbook = WorkbookFactory.create(is);//同时支持2003、2007、2010
// 获取Sheet数量
int sheetNum = workbook.getNumberOfSheets();
sheetNum = 1;//限制模板只在一个工作簿上操作
// 遍历工作簿中的sheet,第一层循环所有sheet表
for(int index = 0;index<sheetNum;index++){
Sheet sheet = workbook.getSheetAt(index);
if(sheet==null){
continue;
}
// 如果当前行没有数据跳出循环,第二层循环单sheet表中所有行
for(int rowIndex=3;rowIndex<=sheet.getLastRowNum();rowIndex++){
Row row = sheet.getRow(rowIndex);
row.createCell(1).setCellValue(result.get(rowIndex-3));
} }
FileOutputStream outputStream = new FileOutputStream(url);
workbook.write(outputStream);
outputStream.close();
}
/**
* 根据地址获得客户上传的excel字节流
* @param fileUrl 网络连接地址
* @return
*/
public static byte[] getExcelFromAliyun(String fileUrl){
try {
URL url = new URL(fileUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();//通过输入流获取excelFile数据
byte[] excelFile = readInputStream(inStream);//得到excelFile的二进制数据
return excelFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 从网上得到的输入流中获取数据转换为二进制数据
* @param inStream 输入流
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while( (len=inStream.read(buffer)) != -1 ){
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
/**
* 将文件写入到目标目录中
* @param excel 文件数据流
* @param fileName 文件保存时的名称
*/
public static void writeFileToDest(byte[] excelFile, File dest){
try {
FileOutputStream out = new FileOutputStream(dest);
out.write(excelFile);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/***
*
* 在项目中创建临时文件
* @throws IOException
* */
public static File createTempFile(String fileName) throws IOException{
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if(!path.exists()) path = new File("");
File upload = new File(path.getAbsolutePath(),"static/images/upload/");
if(!upload.exists()) upload.mkdirs();
File tempFile = new File(upload+"/"+fileName);
if(!tempFile.getParentFile().exists()){
tempFile.getParentFile().mkdirs();//创建父级文件路径
tempFile.createNewFile();//创建文件
}
return tempFile;
}
}

contrller层代码

 @PostMapping("/addBatchDevice")
public ResponseObj addBatchDevice(@RequestBody JSONObject obj) throws IOException{
logger.info("导入批量设备:"+obj.toJSONString());
ResponseObj response = new ResponseObj();
String id = obj.getString("id");
BatchRecord batchRecord = deviceService.selectBatchRecordById(id);
String path = aliConstants.aliyunHostOuter+"/"+batchRecord.getFilePath();
// 将该该文件下载出来保存到项目中
byte[] excelFile = ReadExcelUtil.getExcelFromAliyun(path);
File tempFile = ReadExcelUtil.createTempFile(batchRecord.getFileName());
ReadExcelUtil.writeFileToDest(excelFile, tempFile);
String url = tempFile.getAbsolutePath();
String companyId = null;
String productId = null;
Integer deviceType = null;
String model = null;
String deviceName = null;
boolean flag = ReadExcelUtil.checkExcelTemplate(url);
if(!flag){
response.setData(Defined.STATUS_ERROR);
response.setMessage("文件有误,请根据模板上传文件。");
return response;
}
List<Integer> result = new ArrayList<Integer>();//存放反馈信息
try {
List<List<String>> list = ReadExcelUtil.readExcelInfo(url);
for(int i=0;i<list.size();i++){
if(i==0||i==2){
continue;//跳过模板第1,3行
}
if(i==1){
companyId = list.get(i).get(0);
productId = list.get(i).get(1);
deviceType = Integer.valueOf(list.get(i).get(2));
model = list.get(i).get(3);
deviceName = list.get(i).get(4);
}
if(i>2){
// new一个对象按照相应的字段设置进去就可以了,这里省略对象设置值,字段如下:
Device device = new Device();
String deviceId = IdGen.uuid();
device.setId(deviceId);
//省略部分业务代码
DeviceFields deviceFields = new DeviceFields();
deviceFields.setId(IdGen.uuid());
deviceFields.setDeviceId(deviceId);
//省略部分业务代码
Gateway gateway = new Gateway();
gateway.setId(IdGen.uuid());
//省略部分业务代码
if(!deviceService.checkDeviceUidRepeat(uid)){
// 重复,返回sheet行号,并写入sheet表单中
result.add(1);
continue;
}
// 关联表一个事务处理
boolean flg = deviceService.addDeviceEtc(device, deviceFields, gateway);
if(!flg){
result.add(1);
}else{
result.add(0);
}
}
}
// 将反馈结果写入文件0-成功,1-失败
ReadExcelUtil.writeExcelResult(url, result);
AliYunFileSetting setting = new AliYunFileSetting();
setting.setAccessKeyId(aliConstants.accessKeyId);
setting.setAccessKeySecret(aliConstants.accessKeySecret);
setting.setBucketName(aliConstants.bucketName);
setting.setEndpoint(aliConstants.endpoint);
AliyunFileManager manager = AliyunFileManager.getInstance(setting);
InputStream is = new FileInputStream(tempFile);
String relativePath =aliConstants.excelFilePath;//相对路径
boolean fg = manager.upload(is, relativePath, batchRecord.getFileName());//上传文件与客户上传后生成的文件名相同。
if(fg){
logger.info("反馈已经成功写入文件中!");
// 更新批量记录
batchRecord.setUpdateTime(DateUtil.getNowTimestamp());
deviceService.updateBatchRecordByPrimaryKey(batchRecord);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setMessage("批量导入设备成功!");
response.setStatus(Defined.STATUS_SUCCESS);
return response;
}
@PostMapping("uploadExcel")
public ResponseObj uploadExcel(@RequestParam("excelFile") MultipartFile file,@RequestParam("companyId") String companyId,
@RequestParam("productId") String productId,HttpServletRequest request) throws Exception {
ResponseObj response = new ResponseObj();
response.setData(Defined.STATUS_SUCCESS);
response.setMessage("文件上传成功!");
ResponseObj resp = new ResponseObj();
resp.setData(Defined.STATUS_ERROR);
resp.setMessage("不是文件!");
AliYunFileSetting setting = new AliYunFileSetting();
setting.setAccessKeyId(aliConstants.accessKeyId);
setting.setAccessKeySecret(aliConstants.accessKeySecret);
setting.setBucketName(aliConstants.bucketName);
setting.setEndpoint(aliConstants.endpoint);
AliyunFileManager manager = AliyunFileManager.getInstance(setting);
if(file.isEmpty()){
response.setData(Defined.STATUS_ERROR);
response.setMessage("不是文件!");
return response;
}
String fileName = file.getOriginalFilename();
long fileSize = file.getSize();
File tempFile = ReadExcelUtil.createTempFile(fileName);
String relativePath =aliConstants.excelFilePath;//相对路径
String dir = aliConstants.aliyunHostOuter+"/"+relativePath;//云端绝对路径
File dest = new File(dir);
if(!dest.exists()){ //判断文件目录是否存在
dest.mkdir();//
}
try {
file.transferTo(tempFile);
InputStream is = new FileInputStream(tempFile);
String suffix=fileName.substring(fileName.lastIndexOf("."));//获取原始文件后缀.xlxs(含点)
String newFileName = IdGen.uuid()+suffix;
boolean result = manager.upload(is, relativePath, newFileName);//上传文件,并建立随机文件名。
// boolean result = manager.upload(is, dir, fileName);//上传阿里云,固定文件名
if(result){
response.setData(dir+"/"+newFileName);//返回新建文件名的绝对路径
// 数据库存入相对路径
BatchRecord batchRecord = new BatchRecord();
batchRecord.setFileName(newFileName);
batchRecord.setFilePath(relativePath+"/"+newFileName);
batchRecord.setFileSize(fileSize);
batchRecord.setIsDelete((byte) 0);
batchRecord.setStatus((byte) 0);
batchRecord.setId(IdGen.uuid());
batchRecord.setCreateTime(DateUtil.getNowTimestamp());
// batchRecord.setUpdateTime(DateUtil.getNowTimestamp());
batchRecord.setCompanyId(companyId);
batchRecord.setProductId(productId);
Integer resultNum = deviceService.addBatchRecord(batchRecord);
if(resultNum>0){
tempFile.delete();
return response;
}
return resp;
}else{
resp.setMessage("文件上传失败!");
return resp;
}
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
resp.setMessage("文件上传异常!");
return resp;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
resp.setMessage("文件上传异常!");
return resp;
}
}

模板图片:

完整版excel上传导入读写批量数据并将反馈结果写入远程exel中的更多相关文章

  1. 完整版EXCEL导出 (大框架SpringCloud 业务还是Springboot一套)

    这里用的是easypoi 首先引入jar包 <!-- excel --><dependency> <groupId>cn.afterturn</groupId ...

  2. Markdown 语法手册 - 完整版(上)

    https://blog.csdn.net/witnessai1/article/details/52551362 1. 斜体和粗体 代码: *斜体*或_斜体_ **粗体** ***加粗斜体*** ~ ...

  3. php上传导入文件 nginx-502错误

    4. php程序执行时间过长而超时,检查nginx和fastcgi中各种timeout设置.(nginx 中的  fastcgi_connect_timeout 300;fastcgi_send_ti ...

  4. 常用经典SQL语句大全完整版--详解+实例 《来自网络,很全没整理,寄存与此》

    常用经典SQL语句大全完整版--详解+实例 下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML ...

  5. 探索ORACLE之ASM概念(完整版)

    探索ORACLE之ASM概念(完整版) 本文出自https://www.jb51.net/article/43527.htm ASM是Oracle 10g R2中为了简化Oracle数据库的管理而推出 ...

  6. Excel上传并读取数据

    最近一段时间,维护一个旧系统,其中有一个功能,是把Excel上传,并读取数据进行维护,然后转插入至SQL数据库中.下面Insus.NET使用asp.net 标准上传控件: <asp:FileUp ...

  7. MyBatis Plus 批量数据插入功能,yyds!

    最近 Review 小伙伴代码的时候,发现了一个小小的问题,小伙伴竟然在 for 循环中进行了 insert (插入)数据库的操作,这就会导致每次循环时都会进行连接.插入.断开连接的操作,从而导致一定 ...

  8. MySQL5.6 Replication主从复制(读写分离) 配置完整版

    MySQL5.6 Replication主从复制(读写分离) 配置完整版 MySQL5.6主从复制(读写分离)教程 1.MySQL5.6开始主从复制有两种方式: 基于日志(binlog): 基于GTI ...

  9. 阿里云96页报告详解《云上转型》(10个案例、10大趋势/完整版PPT)

    阿里云96页报告详解<云上转型>(10个案例.10大趋势/完整版PPT) 2017-12-29 14:20阿里云/云计算/技术 ﹃产业前沿超级干货﹄ ﹃数据观○重磅速递﹄ 阿里云研究中心云 ...

随机推荐

  1. Android Studio中 no module 问题,解决方法

    等它执行完以后就好了 或者根据提示手动下载缺失的.

  2. 爬虫实战_爬取豆瓣图书利用csv库存储

    读取csv文件 通过csv.reader()和DictReader()两个函数 reader()函数返回一个迭代器 会包含表头 通过next函数可以跳过,但是它只能通过下标访问数据: DictRead ...

  3. ubuntu14 安装Sublime Text 3

    Step1 从官网下载Sublime Text3 安装包 sublime_text_3_build_3176_x64.tar.bz2,如果有网络问题,请挂VPN或者从其他地方下载. 拷贝至/home/ ...

  4. Design and History FAQ for Python3

    Source : Design and History FAQ for Python3 Why is there no goto? 你可以通过异常来获得一个可以跨函数调用的 "goto 结构 ...

  5. Jenkins安装 maven插件

    Maven Artifact ChoiceListProvider (Nexus)Maven Metadata Plugin for Jenkins CI serverMaven Release Pl ...

  6. nginx 打印详细请求

    log_format main escape=json '{ "@timestamp": "$time_iso8601", ' '"remote_ad ...

  7. 一 SSH整合:Spring整合Struts2的两种方式,struts.xml管理Action&Bean管理Action

    SSH回顾 1 引入jar包 Struts2的jar包 D:\Struts2\struts-2.3.35\apps\struts2-blank\WEB-INF\lib  开发基本包 Struts2有一 ...

  8. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表单:表单控件大小

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. linux动态库(.so)和静态库(.a)的区别

    静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.编译之后程序文件大,但加载快,隔离性也好. 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此在程序运行时 ...

  10. 十三、web应用中路径总结

    1.路径的编写形式:1)<a href="/项目名/资源路径"></a>    <!--超链接--> <form action=" ...