<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          POI 導(dǎo)出 Excel:字體顏色、行列自適應(yīng)、鎖住、合并單元格、一文搞定……

          共 2222字,需瀏覽 5分鐘

           ·

          2022-06-10 19:56

          關(guān)注我們,設(shè)為星標(biāo),每天7:40不見(jiàn)不散,架構(gòu)路上與您共享

          回復(fù)架構(gòu)師獲取資源


          大家好,我是你們的朋友架構(gòu)君,一個(gè)會(huì)寫(xiě)代碼吟詩(shī)的架構(gòu)師。

          'javajgs.com';

          1. 前言

          poi框架可以支持我們?cè)趈ava代碼中, 將數(shù)據(jù)導(dǎo)出成excel,但是實(shí)際開(kāi)發(fā)中, 往往還需要設(shè)置excel字體,顏色,行高,列寬等屬性, 有時(shí)候還需要鎖住單元格, 防止別人講數(shù)據(jù)隨意篡改.

          廢話不多說(shuō), 直接上代碼

          2. 鎖住單元格

          導(dǎo)出excel , 自然就有導(dǎo)入excel 了, 比如導(dǎo)出一些數(shù)據(jù)出來(lái), 修改一些再導(dǎo)入進(jìn)去, 但是這時(shí), 一些基本信息我們不希望用戶隨意去修改, 這里就用到了excel的鎖

          圖片

          sheet.protectSheet(密碼)

          代碼:

          //?創(chuàng)建Excel文件
          HSSFWorkbook?workbook?=?new?HSSFWorkbook();
          HSSFSheet?sheet?=?workbook.createSheet(DateUtils.getDate("yyyyMMdd"));
          //鎖定sheet
          sheet.protectSheet("zgd");

          這樣的話, 這個(gè)sheet都會(huì)被鎖定

          但是我們又希望開(kāi)放一些單元格可以修改 , 這個(gè)時(shí)候就要細(xì)粒度的進(jìn)行設(shè)置了

          創(chuàng)建一個(gè)cellStyle:

          ?CellStyle?unlockCell?=?workbook.createCellStyle();
          ?unlockCell.setLocked(false);

          然后在我們不需要鎖定的單元格上, 給它這個(gè) cellStyle

          ?//?設(shè)置dataRow這一行的第i個(gè)單元格不鎖定
          ?dataRow.getCell(i).setCellStyle(unlockCell);

          3. 設(shè)置列寬

          在鎖定了sheet之后, 會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題, 就是列寬都不能改變了

          這個(gè)時(shí)候沒(méi)辦法, 只能自己設(shè)置列寬了, 現(xiàn)在網(wǎng)上找到的設(shè)置列寬的方法有以下幾個(gè):

          1.自適應(yīng)列寬度:

          sheet.autoSizeColumn(1);
          sheet.autoSizeColumn(1,?true);

          這兩種方式都是自適應(yīng)列寬度,但是注意這個(gè)方法在后邊的版本才提供,poi的版本不要太老。

          注意:第一個(gè)方法在合并單元格的的單元格并不好使,必須用第二個(gè)方法。

          經(jīng)過(guò)測(cè)試,這種自適應(yīng)的api在遇到行數(shù)多一點(diǎn)的數(shù)據(jù)的時(shí)候,就會(huì)耗費(fèi)大量的時(shí)間,1000行花了2分鐘!!!所以盡量不要用

          sheet.trackAllColumnsForAutoSizing();
          sheet.autoSizeColumn(i);

          而且這兩個(gè)方法對(duì)英文數(shù)字還好, 對(duì)中文支持的并不好:

          圖片

          2.用數(shù)組將大概的寬度設(shè)置好,手動(dòng)set寬度

          int[]?width?=?{xxx,xxx};
          for循環(huán)
          sheet.setColumnWidth(i,width[i]);

          3.自己根據(jù)一列數(shù)據(jù)中的最長(zhǎng)的字符串長(zhǎng)度設(shè)置寬度

          所以還是得自己費(fèi)心費(fèi)力去diy :

          判斷這一列的最長(zhǎng)字符串,然后

          int?length?=?str.getBytes().length;
          sheet.setColumnWidth((short)列數(shù),(short)(length*256));

          這里經(jīng)過(guò)我反復(fù)嘗試,我個(gè)人覺(jué)得把最大寬度限制在10000到15000左右是比較合適的, 然后剩下的就交給excel的自動(dòng)換行

          像我這里有很多行的數(shù)據(jù), 不知道哪一行的內(nèi)容最長(zhǎng), 這里簡(jiǎn)單提供兩種思路(方法是很多的, 能達(dá)到目的就行):

          1. 用一個(gè)Map, key是指具體哪一列, List中放的是每行的這一列的內(nèi)容的長(zhǎng)度 , 每遍歷一行的一列, 就map.put(i, list.add(length)), 然后用Collections.max(map.get(i))來(lái)獲取第i列的最長(zhǎng)的長(zhǎng)度
          2. 還是一樣,用一個(gè)map: Map,key是指具體哪一列,value是每行的這一列的內(nèi)容的長(zhǎng)度, map.put(i,Math.max(length,map.get(i))),來(lái)確保map中的key對(duì)應(yīng)的value永遠(yuǎn)是目前的最大的長(zhǎng)度.

          我這里使用的第二種:

          設(shè)置自動(dòng)換行后,不要設(shè)置固定的行高,否則超出的部分也會(huì)被遮住不顯示

          //?創(chuàng)建Excel文件
          HSSFWorkbook?workbook?=?new?HSSFWorkbook();
          HSSFSheet?sheet?=?workbook.createSheet("sheet");
          //設(shè)置樣式
          ?CellStyle?blackStyle?=?workbook.createCellStyle();
          //自動(dòng)換行*重要*
          ?blackStyle.setWrapText(true);

          //存儲(chǔ)最大列寬
          Map?maxWidth?=?new?HashMap<>();
          //?標(biāo)題行
          HSSFRow?titleRow?=?sheet.createRow(0);
          titleRow.setHeightInPoints(20);//目的是想把行高設(shè)置成20px
          titleRow.createCell(0).setCellValue("sku編號(hào)");
          titleRow.createCell(1).setCellValue("商品標(biāo)題");
          titleRow.createCell(2).setCellValue("商品名");
          //?初始化標(biāo)題的列寬,字體
          for?(int?i=?0;?i<=3;i++){
          ????maxWidth.put(i,titleRow.getCell(i).getStringCellValue().getBytes().length??*?256?+?200);
          ????titleRow.getCell(i).setCellStyle(blackStyle);//設(shè)置自動(dòng)換行
          }

          for?(Map?map?:?list)?{
          ????int?currentRowNum?=?sheet.getLastRowNum()?+?1;
          ????//數(shù)據(jù)行
          ????HSSFRow?dataRow?=?sheet.createRow(currentRowNum);
          ????//?記錄這一行的每列的長(zhǎng)度
          ????List?valueList?=?new?ArrayList();

          ????String?val0?=?map.get("skuId")?==?null???"—"?:?((Double)?(map.get("skuId"))).intValue()+"";
          ????valueList.add(val0);
          ????dataRow.createCell(0).setCellValue(val0);
          ????String?val1?=?map.get("title")?==?null???""?:?map.get("title").toString();
          ????valueList.add(val1);
          ????dataRow.createCell(1).setCellValue(val1);
          ????String?val2?=?map.get("goodsName")?==?null???""?:?map.get("goodsName").toString();
          ????valueList.add(val2);
          ????dataRow.createCell(2).setCellValue(val2);
          ????String?val3?=?map.get("catName")?==?null???""?:?map.get("catName").toString();
          ????valueList.add(val3);
          ????dataRow.createCell(3).setCellValue(val3);
          ????String?val4?=?map.get("brandName")?==?null???""?:?map.get("brandName").toString();

          ?????for(int?i?=?0;i<=3;i++){
          ?????????int?length?=?valueList.get(i).toString().getBytes().length??*?256?+?200;
          ?????????//這里把寬度最大限制到15000
          ?????????if?(length>15000){
          ?????????????length?=?15000;
          ?????????}
          ?????????maxWidth.put(i,Math.max(length,maxWidth.get(i)));
          ??????????dataRow.getCell(i).setCellStyle(blackStyle);//設(shè)置自動(dòng)換行
          ????}
          }


          for?(int?i=?0;?i<=3;i++){
          ??????//設(shè)置列寬
          ?????sheet.setColumnWidth(i,maxWidth.get(i));
          ?}

          現(xiàn)在的話, 列寬雖然是比較生硬的套用內(nèi)容長(zhǎng)度來(lái)設(shè)置, 不過(guò)也比之前好多了, 列寬是不能超過(guò)256*256的,否則會(huì)報(bào)錯(cuò),所以我這里設(shè)置的最大列寬為15000,超出的部分會(huì)自動(dòng)換行

          圖片

          4. 設(shè)置行高

          行高就很簡(jiǎn)單了,

          titleRow.setHeightInPoints(20);//目的是想把行高設(shè)置成20px

          注意,設(shè)置了固定行高,自動(dòng)換行就不會(huì)自適應(yīng)行高了

          5. 設(shè)置字體,顏色

          創(chuàng)建CellStyle , 然后創(chuàng)建HSSFFont , 再把HSSFFont注入給CellStyle , 在把CellStyle給cell設(shè)置

          //?設(shè)置字體
          CellStyle?redStyle?=?workbook.createCellStyle();
          HSSFFont?redFont?=?workbook.createFont();
          //顏色
          redFont.setColor(Font.COLOR_RED);
          //設(shè)置字體大小
          redFont.setFontHeightInPoints((short)?10);
          //字體
          //redFont.setFontName("宋體");
          redStyle.setFont(redFont);

          HSSFCell?cell13?=?titleRow.createCell(13);
          cell13.setCellStyle(redStyle);
          cell13.setCellValue("注意:只允許修改銷售價(jià),供應(yīng)價(jià),市場(chǎng)價(jià)和庫(kù)存");
          圖片

          6. 合并單元格

          合并單元格的話,建議先合并,合并之后,在合并的第一行第一列set值就可以了

          //這里代表在第0行開(kāi)始,到0行結(jié)束,從0列開(kāi)始,到10列結(jié)束,進(jìn)行合并,也就是合并第0行的0-10個(gè)單元格
          CellRangeAddress?cellRange1?=?new?CellRangeAddress(0,?0,?(short)?0,?(short)?10);
          ????????????sheet.addMergedRegion(cellRange1);
          ????????????CellRangeAddress

          文章來(lái)源:https://zzzgd.blog.csdn.net/article/details/80627175


          到此文章就結(jié)束了。Java架構(gòu)師必看一個(gè)集公眾號(hào)、小程序、網(wǎng)站(3合1的文章平臺(tái),給您架構(gòu)路上一臂之力,javajgs.com)。如果今天的文章對(duì)你在進(jìn)階架構(gòu)師的路上有新的啟發(fā)和進(jìn)步,歡迎轉(zhuǎn)發(fā)給更多人。歡迎加入架構(gòu)師社區(qū)技術(shù)交流群,眾多大咖帶你進(jìn)階架構(gòu)師,在后臺(tái)回復(fù)“加群”即可入群。



          這些年小編給你分享過(guò)的干貨


          1.idea永久激活碼(親測(cè)可用)

          2.優(yōu)質(zhì)ERP系統(tǒng)帶進(jìn)銷存財(cái)務(wù)生產(chǎn)功能(附源碼)

          3.優(yōu)質(zhì)SpringBoot帶工作流管理項(xiàng)目(附源碼)

          4.最好用的OA系統(tǒng),拿來(lái)即用(附源碼)

          5.SBoot+Vue外賣(mài)系統(tǒng)前后端都有(附源碼

          6.SBoot+Vue可視化大屏拖拽項(xiàng)目(附源碼)


          轉(zhuǎn)發(fā)在看就是最大的支持??

          瀏覽 18
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    床戏麻豆 | 亚洲精品一区二区三区2023年最新 | 国产亚洲中文 | 91国產乱老熟女 | www.人人操.com |