生成Excel表格并上传阿里云存储

 

1.程序内部生成Excel表格

   1.1 表头和数据分离

                 

//表头存储格式
List<String[]> headerGoodsOrderList

String[] h1 = new String[2];
        h1[0] = "id";
        h1[1] = "序号";
        headorder.add(h1);
String[] h2 = new String[2];
        h2[0] = "orderNo";
        h2[1] = "订单号";
        headorder.add(h2);

//数据存储格式
List<Map<String, Object>> list

     个人觉得,表头存储格式的好处在于,可以自定义一些属性,包括后续有可能的合并单元格,背景色等等,都可以预先定义,然后在公共类中或者相应的方法中进行处理

      至于数据,由于想做成通用方法,所以采用了map数组结构。

     

public static InputStream  createExcel(List<String[]> headerList, List<Map<String,Object>> dataList){
        InputStream excelStream = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        //创建HSSFWorkbook对象(excel的文档对象)  
        HSSFWorkbook wb = new HSSFWorkbook();
        // 建立新的sheet对象(excel的表单)
        HSSFSheet sheet = wb.createSheet("sheet1");
        // 在sheet里创建第一行,参数为行索引(excel的行),可以是0~65535之间的任何一个
        HSSFRow row = sheet.createRow(0);
        // 第四步,创建单元格,并设置值表头 设置表头居中
        HSSFCellStyle style = wb.createCellStyle();

        HSSFCell cell = row.createCell((short) 0);

        //设置表头--h[0]英文匹配名,h[1]中文显示字段
        for(int i=0;i<headerList.size();i++){
            String [] arrays = headerList.get(i);
            sheet.setColumnWidth(i, 20 * 256);
            if(i!=0){
                cell = row.createCell((short) i);
            }
            cell.setCellValue(arrays[1]);
            cell.setCellStyle(style);
        }
        //编辑数据--表头匹配
        for(int j=0;j<dataList.size();j++){
            //另起一行
            row = sheet.createRow((int) j + 1);
            Map<String,Object> maps = dataList.get(j);
            for(int k=0;k<headerList.size();k++){
                String [] arr = headerList.get(k);
                row.createCell((short) k).setCellValue(maps.get(arr[0])!=null?maps.get(arr[0]).toString():"");
            }
        }
        try {
            wb.write(out);
            excelStream = new ByteArrayInputStream(out.toByteArray());
            out.close();
        }catch (IOException e) {
            e.printStackTrace();
        }
        return excelStream;
    }

  首先,将定义的表头list集合在单元格中定义,取集合中的list[1],后续list[0]中的英文名做为和数据中的key进行匹配,这样可以减少非必要的循环,增加速度。

  循环装载数据时,需要另起一行

row = sheet.createRow((int) j + 1);

 此行代码在循环基础上加一,避过表头另起一行

 一般没有什么要求直接页面输出的话可以酌情去除我try catch中的代码,但是我这边是要拿到输出流对象上传阿里云接口,然后拿到下载链接返回前端,所以需要转换一下。

String fileName = UUID.randomUUID().toString().replace("-", "").toLowerCase()+".xls";

生成UUID做为文件名,然后正常调用阿里云上传接口即可,可以去查询阿里云上传接口文档。

public byte[] downloadFiles(TmpFile tmpFile) {
        log.info("文件下载,传入文件ID为{}", tmpFile);
        OSSClient client = Upload.getOSSClient();
        String fileName = tmpFile.getFileUrl().substring(tmpFile.getFileUrl().lastIndexOf("/")+1,tmpFile.getFileUrl().length());
        InputStream inputStream = Upload.getOSS2InputStream(client,bucketName,diskNameTmp,fileName);
        try {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024*4];
            int n = 0;
            while (-1 != (n = inputStream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();

        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return null;
    }

这里我把文件下载的方法记录一下,远程下载链接后,解析位byte数组

InputStream inputStream = new ByteArrayInputStream(fileByte);

转为输出流后解析即可 

/**
     * 读入excel文件,解析后返回
     * @param in  inputStream
     * @param fileName 文件名
     */
    public static List<String[]> readExcel(InputStream in,String fileName) {

        //获得Workbook工作薄对象
        Workbook workbook = getWorkBook(in,fileName);
        //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
        List<String[]> list = new ArrayList<String[]>();
        if(workbook != null){
            for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
                //获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(sheetNum);
                if(sheet == null){
                    continue;
                }
                //获得当前sheet的开始行
                int firstRowNum  = sheet.getFirstRowNum();
                //获得当前sheet的结束行
                int lastRowNum = sheet.getLastRowNum();
                //循环除了第一行的所有行
                for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){
                    //获得当前行
                    Row row = sheet.getRow(rowNum);
                    if(row == null){
                        continue;
                    }
                    //获得当前行的开始列
                    int firstCellNum = row.getFirstCellNum();
                    //获得当前行的列数
                    int lastCellNum = row.getLastCellNum();
                    String[] cells = new String[lastCellNum];
                    //循环当前行
                    for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
                        Cell cell = row.getCell(cellNum);
                        cells[cellNum] = getCellValue(cell);
                    }
                    list.add(cells);
                }
            }
            // workbook.close();
        }
        return list;
    }
public static Workbook getWorkBook(InputStream is,String fileName) {
        //创建Workbook工作薄对象,表示整个excel
        Workbook workbook = null;
        try {
            //获取excel文件的io流
            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if(fileName.endsWith(xls)){
                //2003
                workbook = new HSSFWorkbook(is);
            }else if(fileName.endsWith(xlsx)){
                //2007 及2007以上
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new MyException(Messages.ERROR);
        }/*finally {
            if(is !=null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }*/
        return workbook;
    }

对于Excel的解析,以及文件间的上传下载其实都很畏惧,其实,静下心来仔细看看,或许就是新的天地...

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值