POI 導出 Excel:字體顏色、行列自適應、鎖住、合併單元格、一文搞定……

来源:https://www.cnblogs.com/javastack/archive/2022/04/15/16149793.html
-Advertisement-
Play Games

來源:zzzgd.blog.csdn.net/article/details/80627175 1. 前言 poi框架可以支持我們在java代碼中, 將數據導出成excel,但是實際開發中, 往往還需要設置excel字體,顏色,行高,列寬等屬性, 有時候還需要鎖住單元格, 防止別人講數據隨意篡改. ...


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

1. 前言

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

廢話不多說, 直接上代碼

2. 鎖住單元格

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

sheet.protectSheet(密碼)

代碼:

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

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

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

創建一個cellStyle:

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

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

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

3. 設置列寬

在鎖定了sheet之後, 會發現一個問題, 就是列寬都不能改變了

這個時候沒辦法, 只能自己設置列寬了, 現在網上找到的設置列寬的方法有以下幾個:

1.自適應列寬度:

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

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

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

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

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

而且這兩個方法對英文數字還好, 對中文支持的並不好:

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

int[] width = {xxx,xxx};
for迴圈
sheet.setColumnWidth(i,width[i]);

3.自己根據一列數據中的最長的字元串長度設置寬度

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

判斷這一列的最長字元串,然後

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

這裡經過我反覆嘗試,我個人覺得把最大寬度限制在10000到15000左右是比較合適的, 然後剩下的就交給excel的自動換行

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

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

我這裡使用的第二種:

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

// 創建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;
    //數據行
    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));
 }

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

4. 設置行高

行高就很簡單了,

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

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

5. 設置字體,顏色

創建CellStyle , 然後創建HSSFFont , 再把HSSFFont註入給CellStyle , 在把CellStyle給cell設置

// 設置字體
CellStyle redStyle = workbook.createCellStyle();
HSSFFont redFont = workbook.createFont();
//顏色
redFont.setColor(Font.COLOR_RED);
//設置字體大小
redFont.setFontHeightInPoints((short) 10);
//字體
//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(0, 0, (short) 0, (short) 10);
            sheet.addMergedRegion(cellRange1);
            CellRangeAddress

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天結束的挺早,因為今天的內容還可以不是很難,今天全程是學了一些關於mysql資料庫和sql查詢語句的內容包括在node終端裡面怎麼來連接資料庫。經過今天的一個學習,我感覺離那個地步越來越近了,就是那個自己完成一個網站,有伺服器、有響應,就跟現在這些上線的網站一樣一樣的,越來越近了。 1. 這些內容 ...
  • 企業微信 自定義開發H5頁面應用 網頁授權登錄獲取用戶信息 許可權同步 ...
  • 哈嘍大家好我是臉皮賊厚的小威 愚人節剛過先給大家拜個早年吧 最近在HarmonyOS官網下載了IDE,並抱著學(wan)習(wan)的心態試著跑出了Hello World,並安裝到手機上 這是一個簡單到不能再簡單的過程,但是我做的依然磕磕絆絆,遇到很多的問題 在這裡發帖留念記錄一下 第一步安裝IDE ...
  • 為什麼要使用Sapper Sapper是一個用於構建各種規模的Web應用程式的框架,具有出色的開發體驗和靈活的基於文件系統的路由。 與單頁應用程式不同,Sapper不會在SEO,漸進式增強或初始載入體驗方面妥協 - 但與傳統的伺服器渲染應用程式不同,導航對於這種類似應用程式的感覺是即時的。 通過本教 ...
  • 老舊項目二次開髮指南 背景: 最近新入職公司,負責技術。由於各種原因現在項目全權交由我們團隊負責,之前的研發團隊不再參與(及以後可能完全聯繫不上)。作為技術負責人,又剛入職公司壓力巨大。經過兩個多月的改造,算是接手得還算行。該項目存在的問題比較典型,特此記錄。歡迎各位大佬批評指教。技術能力有限,文中 ...
  • Spring 最重要的方法refresh方法 根據上一篇文章 https://www.cnblogs.com/redwinter/p/16141285.html Spring Bean IOC 的創建流程繼續解讀Spring源碼,本篇文章解讀Spring 源碼最重要的方法refresh方法。 這個方 ...
  • 在python的輸出結果中,尤其是浮點數的輸出,當我們需要寫入文本文件時,最好是採用統一的輸出格式,這樣也能夠增強結果的可讀性。而對於浮點數輸出位數的控制,可以通過{:.4f}、%.4f來指定列印或者輸出時的字元串占據空間,也可以通過round函數來對輸出前的結果進行轉化。而如果是取有效數字,需要用... ...
  • 歷史(建議瞭解即可) 一、1990年,美國Sun公司的“Stealth計劃”(後改名為“Green計劃”)目標設置在家用電器等小型系統的程式語言,準備應用在電視機、電話、鬧鐘、烤麵包機等家用電器的控制和通信 二、1996年5月23日,JDK1.0開始發行(前期Java的版本只有兩個) 三、2005年 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...