利用Java自定義格式,循環導出數據、圖片到excel

利用Java自定義格式,循環導出數據、圖片到excel

  • 1、自定義格式循環導出數據
    • 1.1.設置格式
      • 1.1.1、居中樣式
      • 1.1.2、應用樣式到合并區域
      • 1.1.3、合并單元格
      • 1.1.4、設置列寬
    • 1.2、寫入數據
      • 1.2.1、創建標簽頭部
      • 1.2.2、寫入標簽內容
  • 2、自定義格式循環導出圖片
    • 2.1、設置格式并插入圖片
  • 3、格式和數據寫入統一封裝
  • 4、測試方法和效果
    • 4.1、測試方法
    • 4.2、運行效果

1、自定義格式循環導出數據

我有一個需求,需要做一個標簽,格式固定,但是數據從數據庫中獲取,手動一個一個寫不現實,所以我考慮寫個方法,自定義格式,循環的將數據導出到excel。
說明:

因為我要做的一個標簽,占據excel 5行4列,所以在下面的代碼中,會提到 4 5或者這兩數的倍數關系,請注意這個情況

1.1.設置格式

1.1.1、居中樣式

// 創建居中樣式private static CellStyle createCenterStyle(Workbook workbook) {CellStyle style = workbook.createCellStyle();// 水平居中style.setAlignment(HorizontalAlignment.CENTER);// 垂直居中style.setVerticalAlignment(VerticalAlignment.CENTER);// 設置邊框style.setBorderTop(BorderStyle.THIN);style.setBorderBottom(BorderStyle.THIN);style.setBorderLeft(BorderStyle.THIN);style.setBorderRight(BorderStyle.THIN);//字體Font font = workbook.createFont();font.setFontName("微軟雅黑"); // 設置字體類型font.setFontHeightInPoints((short) 8); // 設置字體大小style.setFont(font);return style;}

1.1.2、應用樣式到合并區域

    /*** 應用樣式到合并區域* @param sheet 工作表* @param region 合并區域* @param style 樣式*/private static void applyStyleToMergedRegion(Sheet sheet, CellRangeAddress region, CellStyle style) {for (int row = region.getFirstRow(); row <= region.getLastRow(); row++) {Row sheetRow = sheet.getRow(row) != null ? sheet.getRow(row) : sheet.createRow(row);for (int col = region.getFirstColumn(); col <= region.getLastColumn(); col++) {Cell cell = sheetRow.getCell(col) != null ?sheetRow.getCell(col) : sheetRow.createCell(col);cell.setCellStyle(style);}}}

1.1.3、合并單元格

	/*** 合并單元格并居中* @param sheet 工作表* @param centerStyle 樣式* @param columnsNum 列數* @param lineNum 行數*/private static void mergeAndCenterCells(Sheet sheet, CellStyle centerStyle,int columnsNum, int lineNum) {for (int i = 0; i < lineNum; i=i+5) {for (int j = 0; j < columnsNum; j=j+4) {//標簽頭部的合并區域  同一行 4列CellRangeAddress titleMerge = new CellRangeAddress(i, i, j, j+3);//圖片合并區域 標簽頭部第2行到第5行 第1列到第2列CellRangeAddress photoMerge = new CellRangeAddress(i+1, i+4, j, j+1);//數據合并區域CellRangeAddress queMerge = new CellRangeAddress(i+3, i+3, j+2, j+3);CellRangeAddress timeMerge = new CellRangeAddress(i+4, i+4, j+2, j+3);//寫入工作表sheet.addMergedRegion(titleMerge);sheet.addMergedRegion(photoMerge);sheet.addMergedRegion(queMerge);sheet.addMergedRegion(timeMerge);// 應用居中樣式到合并區域applyStyleToMergedRegion(sheet, titleMerge, centerStyle);applyStyleToMergedRegion(sheet, photoMerge, centerStyle);applyStyleToMergedRegion(sheet, queMerge, centerStyle);applyStyleToMergedRegion(sheet, timeMerge, centerStyle);}}}

1.1.4、設置列寬

循環設置標簽列寬,以適應圖片和數據,大小 1 * 256 為1個字符。

 	/*** 設置列的寬度 以適應圖片和數據* @param columnsNum 列數* @param sheet 工作表*/private static void setColumnWidth(int columnsNum,Sheet sheet){//循環設置標簽的列寬for (int i=0;i<columnsNum;i=i+4){sheet.setColumnWidth(i, 4 * 256); // 設置第一列寬度為4個字符sheet.setColumnWidth(i+1, 4 * 256); // 設置第二列寬度為4個字符sheet.setColumnWidth(i+2, 12 * 256); // 設置第三列寬度為12個字符sheet.setColumnWidth(i+3, 12 * 256); // 設置第四列寬度為12個字符}}

1.2、寫入數據

1.2.1、創建標簽頭部

	/*** 創建標簽頭部* @param sheet 工作表* @param style 居中樣式* @param mainTitleStr 頭部數據* @param columnsNum 列數* @param lineNum 行數*/private static void createHeader(Sheet sheet, CellStyle style,String mainTitleStr,int columnsNum, int lineNum) {for (int i = 0; i < lineNum; i=i+5) {// 隔5行設置一次Row headerRow = sheet.createRow(i);// 主標題(將被合并)for (int j = 0; j < columnsNum; j=j+4) {//隔4列設置一次Cell mainTitle = headerRow.createCell(j);mainTitle.setCellValue(mainTitleStr);mainTitle.setCellStyle(style);}}}

1.2.2、寫入標簽內容

標簽固定的內容可以在這里先寫好,其他有變動的可以從其他渠道獲取后再去拼接。

    /*** 設置內容格式及數據 固定不變的可以在這里寫好 其他從數據庫取到的再去拼接* @param sheet 工作表* @param style 樣式* @param List 從數據庫或其他途徑取到的數據* @param columnsNum 列數* @param lineNum 行數*/private static void createContent(Sheet sheet, CellStyle style,List<Map<Object,Object>> List,int columnsNum, int lineNum) {int lineTemp=0;// 臨時的 行數int columnsTemp=0;// 臨時的 列數for (Map<Object,Object> map:List) {//搞成二位數據 直接固定格式 后續方便固定格式 寫入excel表格Object[][] data = {{"型號:"+map.get("name"), "夾具類型:"+ map.get("type")},{"精度:符合標準", "編號:"+map.get("num")},{"確認人:xxx □    xxx □   "},{"點檢有效期:"+ DateUtil.year(new Date())+"       - "+ DateUtil.year(new Date())+"         "},};//遍歷二維數組for (int i = 0; i < data.length; i++) {int temp=lineTemp+i + 1;//要生成指定行 行數  +1 是因為數據在標簽頭部下面寫入//這么做的目的是 為了避免重新生成一行,導致之前的數據被刪除Row row=sheet.getRow(temp);//獲得之前生成的行if (row==null){//如果之前未生成行 那將需要去生成row = sheet.createRow(temp);}int cellTemp=columnsTemp+2;//指定哪一列 +2是因為前面兩列是設置圖片for (int j = 0; j < data[i].length; j++) {Cell value = row.createCell(cellTemp);row.createCell(cellTemp).setCellValue(data[i][j].toString());//寫入內容value.setCellStyle(style);//設置格式cellTemp+=1;//下一列}}//為了不超過設置的行數 和列數 做出如下判斷if (columnsTemp<columnsNum && (columnsTemp+4)!=columnsNum){columnsTemp=columnsTemp+4;}else {columnsTemp=0;if (lineTemp<lineNum && (lineTemp+5)!=lineNum){lineTemp=lineTemp+5;}else{lineTemp=0;}}}}

2、自定義格式循環導出圖片

在每個標簽中,我都要插入一個二維碼,位置都是固定的,所以就自定義圖片的位置,并且循環插入不同的二維碼。

2.1、設置格式并插入圖片

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** 圖片保存到excel的類*/
public class ImageForExcel {/*** 設置圖片保存到excel的位置* @param workbook excel* @param sheet 工作表* @param photoPath 插入圖片的路徑 一個list集合* @param columnsNum 列數* @param lineNum 行數*/public static void setPhoto(Workbook workbook, Sheet sheet, List<String> photoPath, int columnsNum, int lineNum){int index=0;for (int i = 0; i < lineNum; i=i+5) {for (int j = 0; j < columnsNum; j=j+4) {// 讀取圖片文件try (InputStream is = new FileInputStream(photoPath.get(index))) {// 將圖片轉換為字節數組byte[] bytes = IOUtils.toByteArray(is);// 添加圖片到工作簿int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);// 創建繪圖工具CreationHelper helper = workbook.getCreationHelper();Drawing<?> drawing = sheet.createDrawingPatriarch();// 創建錨點,設置圖片位置ClientAnchor anchor = helper.createClientAnchor();anchor.setCol1(j); // 圖片起始列(0-based)anchor.setRow1(i+1); // 圖片起始行(0-based)anchor.setCol2(j+2); // 圖片結束列(0-based)anchor.setRow2(i+5); // 圖片結束行(0-based)// 創建圖片并設置錨點Picture pict = drawing.createPicture(anchor, pictureIdx);index=index+1;// 可選:調整單元格大小以適應圖片
//            sheet.setColumnWidth(1, 4 * 256); // 調整列寬
//            sheet.setColumnWidth(0, 4 * 256); // 調整列寬/*Row row = sheet.createRow(3);row.setHeightInPoints(100); // 調整行高*/} catch (IOException e) {e.printStackTrace();}}}}
}

3、格式和數據寫入統一封裝

將格式設計和寫入數據的方法同意封裝成一個方法,方便調用。

/*** 統一封裝的方法* @param mainTitleStr 標簽頭部* @param exportPath 導出的路徑 二維碼圖片獲取的路徑* @param columnsNum 標簽的總列數* @param lineNum 標簽的總行數* @param data 變動的數據* @return* @throws Exception*/public static String exportTitle(String mainTitleStr, String exportPath,int columnsNum, int lineNum, List<Map<Object,Object>> data) throws Exception {String excelPath=exportPath+"標簽WZ.xlsx";Workbook workbook = new XSSFWorkbook();Sheet sheet = workbook.createSheet("標簽");//工作表名// 1、設置列寬(單位是1/256個字符寬度)setColumnWidth(columnsNum,sheet);// 設置行高(單位是點,1點=1/20像素)
//        Row row = sheet.createRow(0);
//        row.setHeightInPoints(30); // 設置行高為30點// 2. 創建居中樣式CellStyle centerStyle = createCenterStyle(workbook);// 3. 設置表頭數據createHeader(sheet, centerStyle,mainTitleStr,columnsNum,lineNum);// 4. 設置內容數據createContent(sheet, centerStyle,data,columnsNum,lineNum);// 5. 設置合并區域并應用居中樣式mergeAndCenterCells(sheet, centerStyle,columnsNum,lineNum);//將圖片插入excelList<String> photoPath=new ArrayList<>();for (Map<Object,Object> map:data) {photoPath.add(exportPath+map.get("mold").toString()+".png");}ImageForExcel.setPhoto(workbook,sheet,photoPath,columnsNum,lineNum);// 7. 保存文件try (FileOutputStream out = new FileOutputStream(excelPath)) {workbook.write(out);}return excelPath;}

4、測試方法和效果

文字數據是我自己編的,如果大家要從數據庫或者其他來源獲取,改動data即可。
二維碼圖片是我利用二維碼生成方法生成的,如果大家有興趣,可以看看我上一篇的博客。點擊這里: 二維碼生成方法

4.1、測試方法

這個是有循環生成多個標簽的功能。
所以列數 行數 需要根據自己的需求。
如不需要循環,只需將行列數設置為一個標簽所需要占據的數即可。
目前我的測試方法是,一個標簽占據5行4列,下面設定是有4個標簽。
如果對代碼中 4 5 或者 4 5 倍數 ,又或者其他數據有疑問的話,可以看看這里

import com.codermy.myspringsecurityplus.utils.qrUtils.TitleForExcel;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class BiaoQian {public static void main(String[] args) throws Exception {//1、表頭String mainTitleStr="夾具確認表 DOC-190-AA0004-01D";//2、excel存放的位置String exportPath="D:/java/codeSpace/testFile/";/*這個是有生成多個的功能 所以列數 行數 需要根據自己的需求如不需要循環,只需將行列數設置為一個標簽所需要占據的數即可目前我的數據是,一個標簽占據5行4列,下面設定是循環寫入4個標簽如果對代碼中 4 5  或者 4 5 倍數 ,又或者其他數據有疑問的話,可以看看這里*///3、列數int columnsNum=8;//4、行數int lineNum=10;//5、數據   可以從數據庫中得到 然后再按照我們需要的數據做處理// 下面是我自己模擬的一些數據List<Map<Object,Object>> data=new ArrayList<>();String name="C40888";String type="WZ";//這個 (i < 5) ,需要對應上面的行列數 有四個標簽for (int i = 1; i < 5; i++) {Map<Object,Object> map=new HashMap<>();map.put("name",name);map.put("type",type);map.put("num",i);map.put("mold",name+"-"+type+"-"+i);data.add(map);}String result=TitleForExcel.exportTitle(mainTitleStr,exportPath,columnsNum,lineNum,data);System.out.println(result);}}

4.2、運行效果

由于圖片有二維碼,會被和諧,所以我在二維碼上搞了貼紙,實際導出效果沒有貼紙
在這里插入圖片描述


以上就是本篇文章的全部內容,部分代碼是利用AI生成,然后再去修改成我想要的效果,如果有侵權的地方,還請聯系本人。
本文有很多可以修改優化的地方,如果各位同學有好的見解可以評論留言討論。
如果代碼有異常,或者有其他疑惑、可以評論區留言。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91433.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91433.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91433.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SAP學習筆記 - 開發45 - RAP開發 Managed App New Service Definition,Metadata Extension

上一章講了在 Data Model View ( CDS View for BO Structure )基礎上創建 Projection View ( CDS View for BO Projection )。 SAP學習筆記 - 開發44 - RAP開發 Managed App 建 Projection View&#xff0c;Provider Contract&#xff0c;用 redirected to 設定父子關系-CSDN博…

React強大且靈活hooks庫——ahooks入門實踐之高級類hook(advanced)詳解

什么是 ahooks&#xff1f; ahooks 是一個 React Hooks 庫&#xff0c;提供了大量實用的自定義 hooks&#xff0c;幫助開發者更高效地構建 React 應用。其中高級類 hooks 是 ahooks 的一個重要分類&#xff0c;專門用于處理一些高級場景&#xff0c;如受控值、事件發射器、性能…

計算機網絡——數據鏈路層(25王道最新版)

數據鏈路層前言數據鏈路層的功能封裝成幀&#xff08;組幀&#xff09;字符計數法字節填充法零比特填充法違規編碼法小節差錯控制檢錯編碼奇偶校驗碼CRC校驗碼&#xff08;循環冗余校驗碼&#xff09;基本思想如何構造如何檢錯糾錯糾錯編碼海明校驗碼設計思路求解步驟&#xff…

【PTA數據結構 | C語言版】字符串替換算法

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;將給定主串 s 中的子串 sub_s 替換成另一個給定字符串 t&#xff0c;再輸出替換后的主串 s。 輸入格式&#xff1a; 輸入給出 3 個非空字符串&#xff0c;依次為&#xff1a…

事物生效,訂單類內部更新訂單

代碼如下以下代碼1不生效&#xff0c;2生效解決方案1&#xff0c;外層方法加注解&#xff0c;內層不加2&#xff0c;不要拆分方法&#xff0c;把更新訂單操作放在帶事物的大方法中3&#xff0c;拆方法&#xff08;內部&#xff09;&#xff0c;注入自己&#xff0c;用代理對象調…

非對稱加密:RSA

文章目錄 非對稱加密:RSA 1、RSA 加解密 2、RSA 生成密鑰對(公鑰、私鑰)、加解密 參考資料 非對稱加密:RSA 1、RSA 加解密 <!-- RSA --><!-- 引入jsencrypt庫 --><script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.3.2/jsencrypt.min.js&q…

MongoDB 數據庫 啟用訪問控制

0. 最近服務器安裝了 MongoDB 被勒索了 測試服務器安裝了 MongoDB 等&#xff0c;開放了 27017 對所有 ip。 哈哈哈哈哈哈&#xff0c;問就是有點犯懶&#xff0c;之前都是只允許自己的 ip。 好家伙&#xff0c;然后沒過幾個小時&#xff0c;數據庫集合被清空&#xff0c;只留…

【Unity Sprite屬性拓展】

Unity Inspector 精靈圖預覽為 Unity 中的 Sprite 類型屬性提供了??增強版的 Inspector 顯示??&#xff0c;在保留標準精靈選擇功能的基礎上&#xff0c;添加了大型預覽圖和精靈名稱顯示功能代碼 using UnityEngine; using UnityEditor;// 1?? 告訴 Unity&#xff1a;所有…

細菌實驗入門:濃度測定與菌種鑒定技術詳解

在微生物實驗中&#xff0c;細菌濃度的精準測定和菌種的準確鑒定是兩項基礎且核心的操作。本文將詳細介紹相關技術的原理、操作步驟及注意事項&#xff0c;為新手提供系統性指導。一、細菌濃度測定方法1. 光密度法&#xff08;OD600&#xff09;&#xff1a;快速定量的首選原理…

GaussDB 數據庫架構師修煉(一)數據庫容量規劃

1、容量規劃的定義GaussDB容量規劃是指根據客戶業務系統的負載需求或歷史運行數據&#xff0c;進行合理規劃GaussDB的計算、存儲和網絡資源配置&#xff0c;以滿足業務系統正常使用和未來若干年負載增長訴求的過程。2、容量規劃活動主要步驟需求收集調研生產系統的業務特征&…

hashMap原理(一)

概念HashMap是java中一種非常常用的基于哈希表的數據結構&#xff0c;允許o(1)的時間復雜度進行元素插入&#xff0c;查找&#xff0c;和刪除。它通過”鍵-值“ 對的方式存儲數據。總的來說&#xff1a;HashMap的底層原理&#xff1a;數組鏈表紅黑樹&#xff08;jdk1.8之后還涉…

Ubuntu24 輔助系統-屏幕鍵盤的back按鍵在網頁文本框刪除不正常的問題解決方法

Ubuntu24 輔助系統-屏幕鍵盤的back按鍵異常 問題描述ubuntu24這個屏幕鍵盤&#xff0c;只有在網頁的搜索框或者文本框&#xff0c;比如百度首頁的搜索框&#xff0c;留言的文本框&#xff0c;才會出現點擊back按鈕的時候&#xff0c;出現了先選中當前這個字符&#xff0c;刪除此…

自然語言指令驅動的工業機器人協同學習系統:大語言模型如何重塑智能體協作范式

重磅推薦專欄: 《大模型AIGC》 《課程大綱》 《知識星球》 本專欄致力于探索和討論當今最前沿的技術趨勢和應用領域,包括但不限于ChatGPT和Stable Diffusion等。我們將深入研究大型模型的開發和應用,以及與之相關的人工智能生成內容(AIGC)技術。通過深入的技術解析和實踐經…

web:js的switch語句

在js中,switch語句是一種用于根據不同的條件執行不同代碼塊的控制流語句。它類似于多個if...else if...else語句,但結構更清晰,特別是在有多個條件分支的情況下。 基本語法 switch (expression) {case value1:// 當expression的值等于value1時執行這里的代碼break;case va…

為何說分布式 AI 推理已成為下一代計算方式

2024 年&#xff0c;我們見證了人工智能創新的空前爆發。AI 的快速發展令很多人驚嘆&#xff0c;為了訓練更先進的大語言模型&#xff08;LLM&#xff09;&#xff0c;科技巨頭爭相獲取強大的 GPU。如今&#xff0c;AI 正在無縫融入我們世界的每個角落。在眾多新興 AI 公司、模…

阿里云 RabbitMQ 可觀測性最佳實踐

阿里云 RabbitMQ 阿里云 RabbitMQ 是一款高性能、高可靠的消息中間件&#xff0c;支持多種消息協議和豐富的功能特性。它提供消息隊列功能&#xff0c;能夠實現應用間的消息解耦和異步通信&#xff0c;提升系統擴展性和穩定性。其支持多種消息持久化策略&#xff0c;確保消息不…

vue-router 導航式編程 參數的設置

主要是想記錄一下this.$router.push、replace、go等方法的參數如何設置。字符串路徑router.push(/home)直接使用字符串&#xff08;或模板字符串&#xff09;路徑&#xff0c;可跳轉到相應的URL路徑。對象式路徑路徑也可以是一個對象&#xff0c;對象里以key:value的形式表示UR…

Swift實現股票圖:從基礎到高級

目錄一、核心實現方案1. 原生方案&#xff1a;使用 Core Graphics 繪制2. 使用第三方庫&#xff1a;Charts3. 跨平臺方案&#xff1a;使用 SwiftUI Canvas二、技術指標實現1. 移動平均線 (MA)2. 布林帶 (Bollinger Bands)3. MACD (Moving Average Convergence Divergence)三、…

【unitrix】 6.4 數特征(number.rs)

一、源碼 這段代碼定義了一個名為Number的trait&#xff08;特質&#xff09;以及它的實現。 use crate::sealed::Sealed; use crate::number::{V, BaseNumber, TNumber};/// 數值的統一標記特質 /// 可以是編譯時類型化數字(TNumber)或運行時變量(V<T>) pub trait Numbe…

AI治AI:大語言模型自檢新法

“以火攻火”的思路解決大語言模型(LLMs)“幻覺”問題 虛構是由于與提示無關的內部因素而不可預測地從 LLM 中出現的幻覺。作者專注于衡量 LLM 對提示響應的不確定性,使用高不確定性表示虛構的假設。他們通過計算一個稱為熵的量來估計這種不確定性**,熵可以被認為是模型生…