当前位置: 首页 > 后端技术 > Java

POI导出Excel:字体颜色、行列适配、锁定、合并单元格,全部搞定……

时间:2023-04-01 13:42:40 Java

来源:zzzgd.blog.csdn.net/article/details/806271751。前言poi框架可以支持我们的java代码,导出数据到excel,但是在实际开发中,经常需要设置excel的字体、颜色、行高、列宽等属性,有时还需要锁定单元格来实现防止他人随意篡改数据。废话不多说,直接上代码2.锁定单元格导出excel,自然导入excel,比如导出一些数据,修改一些再导入进去,但是这个时候我们不希望用户修改一些基本信息随意,所以这里我们使用到达excel的locksheet.protectSheet(password)代码//创建Excel文件;//锁定sheetsheet.protectSheet("zgd");在这种情况下,此工作表将被锁定,但我们想打开一些要修改的单元格。这时候我们就需要进行细粒度的设置。创建一个cellStyle:CellStyleunlockCell=workbook.createCellStyle();unlockCell.setLocked(false);ThengiveitthecellStyleonthecellthatwedon'tneedtolock//设置dataRow行中的第i个单元格不锁定dataRow.getCell(i).setCellStyle(unlockCell);3、在sheet中设置列宽锁定sheet后,会发现一个问题,就是列宽无法更改。这个时候没办法,只能自己设置列宽了。现在网上查到设置列宽的方法有以下几种:1、自适应列宽:sheet.autoSizeColumn(1);sheet.autoSizeColumn(1,true);这两个方法都是自适应列宽的,但是注意这个方法是以后版本才提供的,poi的版本不要太旧。注意:第一种方法在合并单元格中效果不佳,必须使用第二种方法。经过测试,这个自适应的api遇到行数多一点的数据会消耗很多时间,1000行需要2分钟!!!所以尽量不要使用sheet.trackAllColumnsForAutoSizing();sheet.autoSizeColumn(i);而这两种方法对英文数字好,对中文不好:2、用数组设置大概宽度,手动设置宽度int[]width={xxx,xxx};for循环sheet.setColumnWidth(i,width[i]);3.根据一列数据中最长的字符串长度来设置宽度,所以还是要努力DIY:判断这一列最长的字符串,然后intlength=str.getBytes().length;sheet.setColumnWidth((short)列数,(short)(length*256));这里经过反复尝试,个人认为将最大宽度限制在10000到15000左右比较合适,然后其他交给Excel自动换行。像我这里有很多行数据,不知道哪一行的内容最长。这里有两个简单的思路(方法有很多种,只要能达到目的):用一个Map,key指的是具体的列,每行该列内容的长度被放置在列表中。当遍历一行中的某一列时,map.put(i,list.add(length)),然后用Collections.max(map.get(i))得到第i列的最长长度还是一样,使用一个map:Map,key指的是具体的列,value是这一行的这一列内容的长度,map.put(i,Math.max(length,map.get(i))),保证map中key对应的value永远是当前的最大长度。第二个我这里用的Type:设置自动换行后,不要设置固定的行高,否则多余部分会被覆盖不显示//创建一个Excel文件HSSFWorkbookworkbook=newHSSFWorkbook();HSSFSheetsheet=workbook.创建工作表(“工作表”);//设置样式CellStyleblackStyle=workbook.createCellStyle();//自动换行*重要*blackStyle.setWrapText(true);//存储最大列宽MapmaxWidth=newHashMap<>();//标题行HSSFRowtitleRow=sheet.createRow(0);titleRow.setHeightInPoints(20);//目的是设置行高为20pxtitleRow.createCell(0).setCellValue("skunumber");titleRow.createCell(1).setCellValue("producttitle");titleRow.createCell(2).setCellValue("ProductName");//初始化标题的列宽,fontfor(inti=0;i<=3;i++){maxWidth.put(i,titleRow.getCell(i).getStringCellValue().getBytes().length*256+200);titleRow.getCell(i).setCellStyle(blackStyle);//设置自动换行}for(Mapmap:list){intcurrentRowNum=sheet.getLastRowNum()+1;//数据行HSSFRowdataRow=sheet.createRow(currentRowNum);//记录这一行每一列的长度ListvalueList=newArrayList();字符串val0=map.get("skuId")==null?"—":((Double)(map.get("skuId"))).intValue()+"";valueList.add(val0);dataRow.createCell(0).setCellValue(val0);字符串val1=map.get("title")==null?"":map.get("标题").toString();valueList.add(val1);dataRow.createCell(1).setCellValue(val1);字符串val2=map.get("goodsName")==null?"":map.get("商品名称").toString();valueList.add(val2);dataRow.createCell(2).setCellValue(val2);字符串val3=map.get("catName")==null?"":map.get("猫名").toString();valueList.add(val3);dataRow.createCell(3).setCellValue(val3);字符串val4=map.get("brandName")==null?"":map.get("brandName").toString();for(inti=0;i<=3;i++){intlength=valueList.get(i).toString().getBytes().length*256+200;//这里把宽度最大限制到15000if(length>15000){length=15000;}maxWidth.put(i,数学.max(长度,maxWidth.get(i)));dataRow.getCell(i).setCellStyle(blackStyle);//设置自动换行}}for(inti=0;i<=3;i++){//设置列宽sheet.setColumnWidth(i,maxWidth.get(我));}现在,虽然列宽应用contentlength来设置比较死板,但比以前好多了,而且列宽不能超过256*256,否则会报错,所以我这里设置的最大列宽为15000,超出的部分会自动换行4.设置行高和行高很简单,titleRow.setHeightInPoints(20);//目的是设置行高20px注意,如果设置固定行高,自动换行不会适应行高setFontHeightInPoints((short)10);//font//redFont.setFontName("宋体");redStyle.setFont(redFont);HSSFCellcell13=titleRow.createCell(13);cell13.setCellStyle(redStyle);cell13.setCellValue(“注意:只允许修改销售价、供货价、市场价和存货”);6.合并单元格如果要合并单元格,建议先合并。合并后,可以设置合并的第一行第一列的值。//这里的意思是从第0行开始,到第0行结束,从第0列开始,到第10列结束,合并,即合并第0行中的0-10个单元格CellRangeAddresscellRange1=newCellRangeAddress(0,0,(短)0,(短)10);sheet.addMergedRegion(cellRange1);CellRangeAddress近期热点文章推荐:1.1,000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。.3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!