POI导出

1.引入依赖


<!--poi-->
#处理excel2003
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

#处理excel2007+、poi-ooxml是poi的升级版
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

2.POI EXCEL文档结构类


HSSFWorkbook excel文档对象

HSSFSheet excel的sheet

HSSFRow excel的行

HSSFCell excel的单元格

HSSFFont excel字体

HSSFName 名称

HSSFDataFormat 日期格式

HSSFHeader sheet头

HSSFFooter sheet尾

HSSFCellStyle cell样式

HSSFDateUtil 日期

HSSFPrintSetup 打印

HSSFErrorConstants 错误信息表

3.POI EXCEL文档结构类 用法

(1)获取导入的.xls文件的工作簿


POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("d:/test.xls"));

#获得工作簿对象
HSSFWorkbook wb = new HSSFWorkbook(fs);
  
#获得表对象
HSSFSheet sheet = wb.getSheetAt(0);
   
#获得表的行
HSSFRow row = sheet.getRow(i);
  
#获得表指定行的单元格 i行的第j个单元格
HSSFCell cell = row.getCell((short) j);

#获得单元格样式
cellStyle = cell.getCellStyle();

(2)新建工作簿


#创建工作簿对象
HSSFWorkbook wb = new HSSFWorkbook();

#创建表对象
HSSFSheet sheet = wb.createSheet("new sheet");

#创建表的行 第一行
HSSFRow row = sheet.createRow((short)0);

#创建单元格的样式
cellStyle = wb.createCellStyle();

#创建指定行的单元格 并给该单元格设置样式 设置值
row.createCell((short)0).setCellStyle(cellStyle).setCellValue(1);

(3)获取行列数量


#创建excel
HSSFWorkbook wb= new HSSFWorkbook();
#创建工作簿sheet
HSSFSheet sheet = wb.createSheet("sheetName");
#修改sheet名字
wb.setSheetName(0,"updateName");
#根据索引获取sheet
HSSFSheet sheet = wb.getSheetAt(0);
#获取sheet名字
String sheetName = hssfWorkbook.getSheetAt(0).getSheetName();
#工作簿一共多少行
int rowcount = sheet.getLastRowNum();
#一行多少列
int cellNum = row.getLastCellNum();

#设置行高、列宽为自适应(应用于指定数据范围)
sheet.getAllocatedRange().get("A1:E14").autoFitRows();
sheet.getAllocatedRange().get("A1:E14").autoFitColumns();
#设置行高、列宽为自适应(应用于整个工作表)
sheet.getAllocatedRange().autoFitRows();
sheet.getAllocatedRange().autoFitColumns();

#指定需要自动缩小字体的单元格范围、设置ShrinkToFit为true(缩小数据以适应单元格)
CellRange cell = (CellRange) sheet.get("A1");
cell.getStyle().setShrinkToFit(true);

(4)设置行高列宽


#必须先设置列宽然后设置行高, 不然列宽没有效果
#设置默认行高, 表示2个字符的高度
sheet.setDefaultRowHeight((short) (2 * 256));
#设置默认列宽, 实际上回多出2个字符
sheet.setDefaultColumnWidth(17);

#设置某一列的宽度
sheet.setColumnWidth((short)0,(short)(2 * 256));
#设置某一行的高度
row.setHeight((short)12);

#设置行高、列宽为自适应(应用于指定数据范围)
sheet.getAllocatedRange().get("A1:E14").autoFitRows();
sheet.getAllocatedRange().get("A1:E14").autoFitColumns();
#设置行高、列宽为自适应(应用于整个工作表)
sheet.getAllocatedRange().autoFitRows();
sheet.getAllocatedRange().autoFitColumns();

#指定需要自动缩小字体的单元格范围、设置ShrinkToFit为true(缩小数据以适应单元格)
CellRange cell = (CellRange) sheet.get("A1");
cell.getStyle().setShrinkToFit(true);

(5)设置单元格内容和类型


#只能设置Date类型日期, 其他类型日期需要转为字符串
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:ss");
LocalDateTime now = LocalDateTime.now();
row.createCell(0).setCellValue(df.format(now));
row.getCell(0).setCellValue(new Date());

#读取为数值、日期、字符串、布尔值类型的单元格内容
cell.getNumericCellValue()、cell.getDateCellValue()、cell.getDateCellValue()、getBooleanCellValue


(6)合并单元格


#合并1、2行, 合并4、5列
CellRangeAddress cra = new CellRangeAddress(0, 1, 3, 4);
#在工作簿中添加该区域
sheetAt.addMergedRegion(cra);
#获取已合并的数量
int mergedRegionNum = sheet.getNumMergedRegions()

(7)保存Excel文件


#保存外来文件
FileOutputStream fileOut = new FileOutputStream(path);   
wb.write(fileOut);

#将excel转为byte输出流、将wb转成byte数组
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);

(8)POI获取Excel单元格各种类型的值



4.POI EXCEL文档示例

		XSSFWorkbook wb = new XSSFWorkbook();
        //获取第一个工作簿
        XSSFSheet sheet = wb.createSheet("物联网卡");

        //头部字体
        XSSFFont topFont = wb.createFont();
        //是否加粗
        topFont.setBold(true);
        //字体类型
        topFont.setFontName("Arial");
        //字体型号
        topFont.setFontHeightInPoints((short) 11);
		
		//设置默认列宽和行高(字体高度)
        sheet.setDefaultColumnWidth(4);
        sheetAt.setDefaultRowHeight(font.getFontHeight());

 		//设置表头样式
        XSSFCellStyle topStyle = wb.createCellStyle();
        //背景色填充
        topStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        topStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //水平居中
        topStyle.setAlignment(HorizontalAlignment.CENTER);
        //垂直居中
        topStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //表格样式
        topStyle.setBorderLeft(BorderStyle.THIN);
        topStyle.setBorderRight(BorderStyle.THIN);
        topStyle.setBorderTop(BorderStyle.THIN);
        topStyle.setBorderBottom(BorderStyle.THIN);
        topStyle.setFont(topFont);

        //内容字体
        XSSFFont contentFont = wb.createFont();
        contentFont.setFontName("Arial");
        contentFont.setFontHeightInPoints((short) 11);

        //设置内容样式
        XSSFCellStyle firstStyle = wb.createCellStyle();
        //水平 左对齐
        firstStyle.setAlignment(HorizontalAlignment.LEFT);
        firstStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置自动换行
        firstStyle.setWrapped(true);
        firstStyle.setBorderLeft(BorderStyle.THIN);
        firstStyle.setBorderRight(BorderStyle.THIN);
        firstStyle.setBorderTop(BorderStyle.THIN);
        firstStyle.setBorderBottom(BorderStyle.THIN);
        firstStyle.setFont(contentFont);

        //创建表头
        XSSFRow row = sheet.createRow(0);
        row.createCell(0).setCellValue("加油站名称");
        row.createCell(1).setCellValue("设备名称");
        row.createCell(2).setCellValue("设备ID");
        row.createCell(3).setCellValue("系统ID");
        row.createCell(4).setCellValue("物联网卡ID");
        row.createCell(5).setCellValue("信息更新时间");
        //合并单元格
        XSSFRow row1 = sheet.createRow(1);
        CellRangeAddress cra = new CellRangeAddress(1, 1, 0, 1);
        sheet.addMergedRegion(cra);
        row1.createCell(0).setCellValue("考核对象");
        
        cra = new CellRangeAddress(1, 1, 2, 3);
        sheet.addMergedRegion(cra);
        row1.createCell(2).setCellValue("考核名称");
        
        //设置列宽(每一列的宽度, 合并单元格是列宽相加)
        sheet.setColumnWidth(0, 10000);
        sheet.setColumnWidth(1, 3500);
        sheet.setColumnWidth(2, 3500);
        sheet.setColumnWidth(3, 3500);
        sheet.setColumnWidth(4, 7000);
        sheet.setColumnWidth(5, 7000);
        
        //填充内容
        if (CollectionUtils.isNotEmpty(list)) {
            int rowNum = 1;
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (DeviceRelevantVO vo : list) {

                row = sheet.getRow(rowNum);
                if (row == null) {
                    row = sheet.createRow(rowNum);
                }
                row.createCell(0).setCellValue(vo.getGasStationName());
                row.createCell(1).setCellValue(vo.getDeviceName());
                row.createCell(2).setCellValue(vo.getDeviceId());
                row.createCell(3).setCellValue(vo.getSystemId());
                row.createCell(4).setCellValue(vo.getIccId());
                row.createCell(5).setCellValue(df.format(vo.getUpdateTime()));
				//设置了固定列宽, 根据字体长度设置某一行的高度
				//获取某一列的宽度
				Integer cellWidth = sheetAt.getColumnWidth(10) * 6;
				//字体的高度
                 short fontHeight = topFont.getFontHeight();
                 //cell内容字符串总宽度
                 double cellContentWidth = vo.getName().trim().getBytes().length * 256;
                 //字符串须要的行数 不作四舍五入之类的操做
                 double stringNeedsRows = (double)cellContentWidth / cellWidth;
                 //小于一行补足一行
                 if(stringNeedsRows <= 1.0){
                   double stringNeedsHeight;
                   stringNeedsRows = 1.0;
                   stringNeedsHeight = fontHeight*1.5 * stringNeedsRows;
                   row4.setHeight((short)stringNeedsHeight);
                }
                rowNum++;
            }

        }
        
		//添加样式
		for (int i = 0; i <= sheetAt.getLastRowNum(); i++) {
            Row row = sheetAt.getRow(i);
            if (row == null) {
                row = sheetAt.createRow(i);
            }
            int cellNum = row.getLastCellNum();
            for (int j = 0; j <= cellNum; j++) {
                Cell cell = row.getCell(j);
                if (cell == null) {
                    cell = row.createCell(j);
                }
                cell.setCellStyle(cellStyle);
                if ((i == 0 && j == 0) || ((i == 2 || i == 8) && (j == 0 || j == 1))) {
                    cell.setCellStyle(topStyle);
                }
            }
        }
        
        //传入HttpServletResponse response 输出导出结果 要求方法都为void()
        ServletOutputStream out = null;
        try {
            String fileName = "物联网卡";
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");
            out = response.getOutputStream();
            //将workbook转成byte数组
            wb.write(out);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(ResponseStatus.FILE_DOWNLOAD_FAIL);
        }finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                }catch (Exception e){
                    log.error(e.getMessage(), e);
                }
            }
        }

		//不传参数 输出导出结果 要求方法都为Object
		//将excel转为byte输出
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //将workbook转成byte数组
        hssfWorkbook.write(bos);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentLength(bos.toByteArray().length);
        headers.setContentDispositionFormData("trainingCheck", "考核训练模板" + ".xls");

        //response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,
        // 并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bos.toByteArray(), headers, HttpStatus.OK);
        bos.close();
        return responseEntity;
	

5. POI Excel打印设置


		XSSFWorkbook workbook = new XSSFWorkbook();

       XSSFSheet sheet = workbook.createSheet("自定义sheet名字");
       //这个是sheet缩放设置, 默认打印一页要true
       sheet.setAutobreaks(true);
		// 页边距(下)
       sheet.setMargin(Sheet.BottomMargin,( double ) 0.5 );
		// 页边距(左)
       sheet.setMargin(Sheet.LeftMargin,( double ) 0.1 );
		// 页边距(右)
       sheet.setMargin(Sheet.RightMargin,( double ) 0.1 );
		// 页边距(上)
       sheet.setMargin(Sheet.TopMargin,( double ) 0.5 );
		//设置打印页面为水平居中
       sheet.setHorizontallyCenter(true);
		//设置打印页面为垂直居中
       sheet.setVerticallyCenter(true);
      	//使用POI输出Excel时打印页面
     	//启用“适合页面”打印选项的标志。(默认选择的是“将工作表调整为一页”)
       sheet.setFitToPage(true);

       XSSFPrintSetup printSetup = sheet.getPrintSetup();
		// 打印方向,true:横向,false:纵向
       printSetup.setLandscape(false); 
		//纸张大小,自选A4
       printSetup.setPaperSize(XSSFPrintSetup.A4_PAPERSIZE); 

6. 实战 – 按行导出(无一对多的数据)

 /**
     * 请假记录流水导出
     * @param list
     * @return
     */
    public static ResponseEntity<byte[]> leaveUserCarStepImport(List<LeaveUserCarStepVO> list) throws Exception{

        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        //获取第一个工作簿
        HSSFSheet sheetAt = hssfWorkbook.createSheet("Sheet1");
        //设置表头样式
        HSSFCellStyle topStyle = hssfWorkbook.createCellStyle();
        topStyle.setAlignment(HorizontalAlignment.CENTER);
        topStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        topStyle.setWrapText(true);
        //字体
        HSSFFont topFont = hssfWorkbook.createFont();
        topFont.setBold(true);
        topFont.setFontName(Constants.DownEnum.SONG_TI.getValue());
        topStyle.setFont(topFont);

        //设置内容样式
        HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
        //水平居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        //垂直居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //自动换行
        cellStyle.setWrapText(true);
        //字体
        HSSFFont cellFont = hssfWorkbook.createFont();
        cellFont.setFontName(Constants.DownEnum.SONG_TI.getValue());
        cellStyle.setFont(cellFont);

        //表头 占两行 合并单元格
        HSSFRow row0 = sheetAt.createRow(0);

        CellRangeAddress cra = new CellRangeAddress(0, 1, 0, 0);
        sheetAt.addMergedRegion(cra);
        row0.createCell(0).setCellValue("序号");

        cra = new CellRangeAddress(0, 1, 1, 3);
        sheetAt.addMergedRegion(cra);
        row0.createCell(1).setCellValue("单位名称");

        cra = new CellRangeAddress(0, 1, 4, 5);
        sheetAt.addMergedRegion(cra);
        row0.createCell(4).setCellValue("申请人");

        cra = new CellRangeAddress(0, 1, 6, 7);
        sheetAt.addMergedRegion(cra);
        row0.createCell(6).setCellValue("用车类型");

        cra = new CellRangeAddress(0, 1, 8, 10);
        sheetAt.addMergedRegion(cra);
        row0.createCell(8).setCellValue("开始时间");

        cra = new CellRangeAddress(0, 1, 11, 13);
        sheetAt.addMergedRegion(cra);
        row0.createCell(11).setCellValue("结束时间");

        cra = new CellRangeAddress(0, 1, 14, 16);
        sheetAt.addMergedRegion(cra);
        row0.createCell(14).setCellValue("用车时长");

        cra = new CellRangeAddress(0, 1, 17, 19);
        sheetAt.addMergedRegion(cra);
        row0.createCell(17).setCellValue("车牌号");

        cra = new CellRangeAddress(0, 1, 20, 21);
        sheetAt.addMergedRegion(cra);
        row0.createCell(20).setCellValue("司机");

        cra = new CellRangeAddress(0, 1, 22, 23);
        sheetAt.addMergedRegion(cra);
        row0.createCell(22).setCellValue("审批人");

        cra = new CellRangeAddress(0, 1, 24, 26);
        sheetAt.addMergedRegion(cra);
        row0.createCell(24).setCellValue("同行人员");

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //内容
        for (int i = 0; i < list.size(); i++) {
            int hangNum = i + 2;
            HSSFRow row = sheetAt.getRow(hangNum);
            if (row == null) {
                row = sheetAt.createRow(hangNum);
            }
            LeaveUserCarStepVO vo = list.get(i);
            if (vo == null) {
                continue;
            }
            //序号
            row.createCell(0).setCellValue(i+1);
            //单位名称
            cra = new CellRangeAddress(hangNum, hangNum, 1, 3);
            sheetAt.addMergedRegion(cra);
            row.createCell(1).setCellValue(vo.getCampName() == null ? "" : vo.getCampName().trim());
            //申请人
            cra = new CellRangeAddress(hangNum, hangNum, 4, 5);
            sheetAt.addMergedRegion(cra);
            row.createCell(4).setCellValue(vo.getEmployeeName() == null ? "" : vo.getEmployeeName().trim());
            //用车类型
            cra = new CellRangeAddress(hangNum, hangNum,6, 7);
            sheetAt.addMergedRegion(cra);
            row.createCell(6).setCellValue(vo.getUserCarType() == null ? "" : vo.getUserCarType().trim());
            //开始时间
            cra = new CellRangeAddress(hangNum, hangNum, 8, 10);
            sheetAt.addMergedRegion(cra);
            row.createCell(8).setCellValue(vo.getBeginTime() == null ? "" : df.format(vo.getBeginTime()));
            //结束时间
            cra = new CellRangeAddress(hangNum, hangNum, 11, 13);
            sheetAt.addMergedRegion(cra);
            row.createCell(11).setCellValue(vo.getEndTime() == null ? "" : df.format(vo.getEndTime()));
            //用车时长
            cra = new CellRangeAddress(hangNum, hangNum, 14, 16);
            sheetAt.addMergedRegion(cra);
            row.createCell(14).setCellValue(vo.getLeaveDuration() == null ? "" : vo.getLeaveDuration().trim());
            //车牌号
            cra = new CellRangeAddress(hangNum, hangNum, 17, 19);
            sheetAt.addMergedRegion(cra);
            row.createCell(17).setCellValue(vo.getLicensePlate() == null ? "" : vo.getLicensePlate().trim());
            //司机
            cra = new CellRangeAddress(hangNum, hangNum,20, 21);
            sheetAt.addMergedRegion(cra);
            row.createCell(20).setCellValue(vo.getDriverName() == null ? "" : vo.getDriverName().trim());
            //审批人
            cra = new CellRangeAddress(hangNum, hangNum,22, 23);
            sheetAt.addMergedRegion(cra);
            row.createCell(22).setCellValue(vo.getApprovalName() == null ? "" : vo.getApprovalName().trim());
            //同行人员
            cra = new CellRangeAddress(hangNum, hangNum, 24, 26);
            sheetAt.addMergedRegion(cra);
            row.createCell(24).setCellValue(vo.getTogetherEmployees() == null ? "" : vo.getTogetherEmployees().trim());
        }

        //单元格样式
        for (int i = 0; i <= sheetAt.getLastRowNum(); i++) {
            Row row = sheetAt.getRow(i);
            if (row == null) {
                row = sheetAt.createRow(i);
            }
            int cellNum = row.getLastCellNum();
            for (int j = 0; j <= cellNum; j++) {
                Cell cell = row.getCell(j);
                if (cell == null) {
                    cell = row.createCell(j);
                }
                cell.setCellStyle(cellStyle);
                if (i == 0) {
                    cell.setCellStyle(topStyle);
                }
            }
        }

        //将excel转为byte输出
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //将workbook转成byte数组
        hssfWorkbook.write(bos);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentLength(bos.toByteArray().length);
        headers.setContentDispositionFormData("leaveUserCarStepImport", "leaveUserCarStepImport" + ".xls");

        //response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,
        // 并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bos.toByteArray(), headers, HttpStatus.OK);
        bos.close();
        return responseEntity;

    }

7. 实战 - 按行读取word文档数据


      try {
            // 打开Word文档
            FileInputStream fis = new FileInputStream(new File("test.docx"));
            XWPFDocument document = new XWPFDocument(fis);

            // 遍历段落
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            int i = 1;
            for (XWPFParagraph paragraph : paragraphs) {
                System.out.println("*****************段落:" + i);
                System.out.println(paragraph.getText());
                i++;
            }
            // 遍历表格
            List<XWPFTable> tables = document.getTables();
            for (XWPFTable table : tables) {
                List<XWPFTableRow> rows = table.getRows();
                for (XWPFTableRow row : rows) {
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        System.out.println(cell.getText());
                    }
                }
            }
            System.out.println(paragraphs);
            // 关闭文件流
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值