<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導出excel:設置字體顏色、行高自適應、列寬自適應、鎖住單元格、合并單元格

          共 6765字,需瀏覽 14分鐘

           ·

          2021-09-21 10:53

          來源:zzzgd.blog.csdn.net/article/details/80627175

          1. 前言

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

          廢話不多說, 直接上代碼

          2. 鎖住單元格

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

          sheet.protectSheet(密碼)

          代碼:

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

          這樣的話, 這個sheet都會被鎖定

          但是我們又希望開放一些單元格可以修改 , 這個時候就要細粒度的進行設置了

          創(chuàng)建一個cellStyle:

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

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

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

          3. 設置列寬

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

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

          1.自適應列寬度:

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

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

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

          經(jīng)過測試,這種自適應的api在遇到行數(shù)多一點的數(shù)據(jù)的時候,就會耗費大量的時間,1000行花了2分鐘!!!所以盡量不要用

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

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

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

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

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

          所以還是得自己費心費力去diy :

          判斷這一列的最長字符串,然后

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

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

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

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

          我這里使用的第二種:

          設置自動換行后,不要設置固定的行高,否則超出的部分也會被遮住不顯示

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

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

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

              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);//設置自動換行
              }
          }


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

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

          4. 設置行高

          行高就很簡單了,

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

          注意,設置了固定行高,自動換行就不會自適應行高了

          5. 設置字體,顏色

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

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

          HSSFCell cell13 = titleRow.createCell(13);
          cell13.setCellStyle(redStyle);
          cell13.setCellValue("注意:只允許修改銷售價,供應價,市場價和庫存");

          6. 合并單元格

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

          //這里代表在第0行開始,到0行結束,從0列開始,到10列結束,進行合并,也就是合并第0行的0-10個單元格
          CellRangeAddress cellRange1 = new CellRangeAddress(00, (short0, (short10);
                      sheet.addMergedRegion(cellRange1);
                      CellRangeAddress

          Java 數(shù)組轉 List 的三種方式及對比

          用好 Java 中的枚舉,讓你的工作效率飛起來!

          4 款 MySQL 調(diào)優(yōu)工具,公司大神都在用!

          面試官問:數(shù)據(jù)庫 delete 表數(shù)據(jù),磁盤空間還是被一直占用,為什么?

          最近面試BAT,整理一份面試資料Java面試BATJ通關手冊,覆蓋了Java核心技術、JVM、Java并發(fā)、SSM、微服務、數(shù)據(jù)庫、數(shù)據(jù)結構等等。

          獲取方式:點“在看”,關注公眾號并回復 Java 領取,更多內(nèi)容陸續(xù)奉上。

          文章有幫助的話,在看,轉發(fā)吧。

          謝謝支持喲 (*^

          瀏覽 56
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  AAA免费视频 | 日本少妇无码精品18p | 欧美黄色操逼 | 欧美另类性爱 | 精品国产AV网站 |