最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)Excel導(dǎo)出的全部流程(多Sheet、復(fù)雜格式)

 更新時(shí)間:2025年12月22日 09:26:06   作者:喝汽水的貓^  
這篇文章主要介紹了如何根據(jù)圖片格式導(dǎo)出Excel文件,并根據(jù)項(xiàng)目號區(qū)分不同的sheet頁,通過Maven依賴、實(shí)體類定義、導(dǎo)出工具和使用示例,詳細(xì)描述了如何實(shí)現(xiàn)這一功能,包括Sheet分組邏輯、格式還原和動(dòng)態(tài)數(shù)據(jù)處理,需要的朋友可以參考下

需求:

1、根據(jù)如下圖片,導(dǎo)出同樣格式的excel文件。
2、并且list實(shí)體集合有項(xiàng)目號,根據(jù)項(xiàng)目號區(qū)分導(dǎo)出不同sheet頁。項(xiàng)目號格式:G10086B1,G10087B1,去掉最后兩位B1或B2在區(qū)分,比如G10086,G10086為一個(gè)sheet頁。G10087又為一個(gè)新的sheet頁。

一、依賴引入(Maven)

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version>
</dependency>

二、完整的實(shí)體類定義

import lombok.Data;
import java.io.Serializable;

/**
 - 入庫單實(shí)體類(完全對應(yīng)Excel表格字段)
 */
@Data
public class WarehouseIn implements Serializable {
    private static final long serialVersionUID = 1L;

    // 1. 序號(Excel第1列,導(dǎo)出時(shí)自動(dòng)生成,無需手動(dòng)設(shè)置)
    private Integer serialNo;

    // 2. 日期(Excel第2列)
    private String date;

    // 3. 所屬車間(Excel第3列)
    private String workshop;

    // 4. 項(xiàng)目號(Excel第4列,格式如GPC25061095B2,用于分組Sheet)
    private String projectNo;

    // 5. 機(jī)臺(tái)(Excel第5列)
    private String machine;

    // 6. 模號(Excel第6列)
    private String modelNo;

    // 7. 任務(wù)包編碼(Excel第7列)
    private String taskPackageCode;

    // 8. 任務(wù)包名稱(Excel第8列)
    private String taskPackageName;

    // 9. 入庫數(shù)量(Excel第9列)
    private Integer inStockQty;

    // 10. 實(shí)收數(shù)(Excel第10列)
    private Integer actualReceivedQty;

    // 11. 班(Excel第11列,如:早班/中班/晚班)
    private String workShift;

    // 12. 組(Excel第12列,如:1組/2組)
    private String workGroup;

    // 13. 組員(Excel第13列,如:張三/李四)
    private String groupMember;

    // 14. 備注(Excel第14列)
    private String remarks;

    // 擴(kuò)展字段(Excel中隱藏的輔助字段,用于填充表頭信息)
    // 填單日期(Excel表頭-填單日期)
    private String fillDate;

    // 交付批次(Excel表頭-交付批次,如:第二批(2+2))
    private String deliveryBatch;

    // 單號(Excel表頭-單號,如:GEN2025131)
    private String orderNo;
}

實(shí)體類說明:

  • 字段對應(yīng)關(guān)系:每個(gè)字段與 Excel 表格列完全對齊,字段名采用「業(yè)務(wù)語義 + 字段類型」命名,便于理解和維護(hù)。
  • 擴(kuò)展字段:fillDate(填單日期)、deliveryBatch(交付批次)、orderNo(單號)是 Excel 表頭的動(dòng)態(tài)信息,實(shí)體類中新增這些字段用于填充,避免硬編碼。
  • 序列化:實(shí)現(xiàn)Serializable接口,支持分布式場景下的數(shù)據(jù)傳輸(如 Redis 緩存、RPC 調(diào)用)。
  • Lombok 注解:使用@Data自動(dòng)生成getter/setter/toString等方法,簡化代碼。

三、代碼實(shí)現(xiàn)

1、導(dǎo)出工具

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ExcelExportUtil {

			/**
	     * 生產(chǎn)入庫單導(dǎo)出
	     */
	    @Override
	    public void exportWarehouseInExcel(OutputStream outputStream, List<StockInEntity> list) throws IOException {
	        // 按項(xiàng)目號分組(去掉最后兩位,如GPC25061095B2 → GPC25061095)
	        Map<String, List<StockInEntity>> groupByProject = list.stream()
	                .filter(item -> isValidProjectNumber(item.getProjectNumber()))
	                .collect(Collectors.groupingBy(item -> truncateProjectNumber(item.getProjectNumber())));
	
	        // 創(chuàng)建Workbook并自動(dòng)關(guān)閉
	        try (Workbook workbook = new XSSFWorkbook()) {
	
	            // 為每個(gè)分組創(chuàng)建Sheet
	            for (Map.Entry<String, List<StockInEntity>> entry : groupByProject.entrySet()) {
	                String sheetName = entry.getKey() + "項(xiàng)目"; // Sheet名(如GPC25061095項(xiàng)目)
	                Sheet sheet = workbook.createSheet(sheetName);
	                List<StockInEntity> sheetData = entry.getValue();
	
	                // 構(gòu)建當(dāng)前Sheet的入庫單內(nèi)容
	                buildStockInEntitySheet(sheet, sheetData);
	            }
	
	            // 寫出Excel
	            workbook.write(outputStream);
	        }
	    }
	
	    // 判斷項(xiàng)目編號是否合法
	    private boolean isValidProjectNumber(String projectNo) {
	        return projectNo != null && projectNo.length() >= 2;
	    }
	
	
	    // 截取項(xiàng)目編號(去掉最后兩位)
	    private String truncateProjectNumber(String projectNo) {
	        if (!isValidProjectNumber(projectNo)) {
	            throw new IllegalArgumentException("Invalid project number: " + projectNo);
	        }
	        return projectNo.substring(0, projectNo.length() - 2);
	    }
	
	    /**
	     * 構(gòu)建單個(gè)Sheet的入庫單格式
	     */
	    private static void buildStockInEntitySheet(Sheet sheet, List<StockInEntity> data) {
	        // 指定時(shí)區(qū)
	        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
	        // 獲取指定時(shí)區(qū)的當(dāng)前日期
	        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
	        String formattedDate = LocalDate.now(zoneId).format(formatter);
	
	        // ========== 設(shè)置列寬 ==========
	        int[] columnWidths = {2500, 3500, 5000, 6000, 4000, 4500, 5500, 6500, 3000, 3000, 3000, 3000, 7000, 3000};
	        for (int i = 0; i < columnWidths.length; i++) {
	            sheet.setColumnWidth(i, columnWidths[i]);
	        }
	
	        // ==========  創(chuàng)建樣式 ==========
	        Workbook workbook = sheet.getWorkbook();
	        // 標(biāo)題樣式(居中、加粗)
	        CellStyle titleStyle = workbook.createCellStyle();
	        Font titleFont = workbook.createFont();
	        titleFont.setBold(true);
	        titleFont.setFontHeightInPoints((short) 16);
	        titleStyle.setFont(titleFont);
	        titleStyle.setAlignment(HorizontalAlignment.CENTER);
	        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
	
	        // 表頭樣式(灰色背景、居中)
	        CellStyle headerStyle = workbook.createCellStyle();
	        Font headerFont = workbook.createFont();
	        headerFont.setBold(true);
	        headerFont.setColor(IndexedColors.WHITE.getIndex());
	        headerStyle.setFont(headerFont);
	        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
	        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
	        headerStyle.setAlignment(HorizontalAlignment.CENTER);
	        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
	        headerStyle.setBorderTop(BorderStyle.THIN);
	        headerStyle.setBorderBottom(BorderStyle.THIN);
	        headerStyle.setBorderLeft(BorderStyle.THIN);
	        headerStyle.setBorderRight(BorderStyle.THIN);
	
	        // 內(nèi)容樣式(居中、邊框)
	        CellStyle contentStyle = workbook.createCellStyle();
	        Font row4Font = workbook.createFont();
	        row4Font.setBold(true);
	        contentStyle.setFont(row4Font);
	        contentStyle.setAlignment(HorizontalAlignment.CENTER);
	        contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
	        contentStyle.setBorderTop(BorderStyle.THIN);
	        contentStyle.setBorderBottom(BorderStyle.THIN);
	        contentStyle.setBorderLeft(BorderStyle.THIN);
	        contentStyle.setBorderRight(BorderStyle.THIN);
	
	        // ==========  構(gòu)建Sheet內(nèi)容 ==========
	        // 第1行:入庫單標(biāo)題(合并單元格)
	        Row row1 = sheet.createRow(0);
	        Cell cell1 = row1.createCell(0);
	        cell1.setCellValue("入庫單");
	        cell1.setCellStyle(titleStyle);
	        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 13)); // 合并A1-N1
	
	        // 第2行:填單日期、項(xiàng)目號等信息(合并單元格)
	        CellStyle row2Style = workbook.createCellStyle();
	        Font row2Font = workbook.createFont();
	        row2Font.setUnderline(Font.U_SINGLE); // 單下劃線(也可以用U_DOUBLE表示雙下劃線)
	        row2Font.setBold(true);
	        row2Style.setFont(row2Font);
	        row2Style.setFillForegroundColor(IndexedColors.WHITE.getIndex());
	        row2Style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
	        row2Style.setAlignment(HorizontalAlignment.CENTER);
	        row2Style.setVerticalAlignment(VerticalAlignment.CENTER);
	        // 創(chuàng)建行并設(shè)置高度
	        Row row2 = sheet.createRow(1);
	        row2.setHeightInPoints((short) 35);
	        // 填單日期(A2-B2)
	        Cell cell2A = row2.createCell(0);
	        cell2A.setCellValue("填單日期:" + formattedDate);
	        cell2A.setCellStyle(row2Style);
	        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 1));
	        // 項(xiàng)目號(C2-F2)
	        Cell cell2C = row2.createCell(2);
	        cell2C.setCellValue("項(xiàng)目號:" + data.get(0).getProjectNumber().substring(0, data.get(0).getProjectNumber().length() - 2));
	        cell2C.setCellStyle(row2Style);
	        sheet.addMergedRegion(new CellRangeAddress(1, 1, 2, 5));
	        // 交付批次(G2-J2)
	        Cell cell2G = row2.createCell(6);
	        cell2G.setCellValue("交付批次:" + data.get(0).getDeliveryBatch());
	        cell2G.setCellStyle(row2Style);
	        sheet.addMergedRegion(new CellRangeAddress(1, 1, 6, 9));
	        // 單號(K2-N2)
	        Cell cell2K = row2.createCell(10);
	        cell2K.setCellValue("單號:" + data.get(0).getInputNo());
	        cell2K.setCellStyle(row2Style);
	        sheet.addMergedRegion(new CellRangeAddress(1, 1, 10, 13));
	
	        // 第3行:表頭(序號、日期、所屬車間...)
	        Row row3 = sheet.createRow(2);
	        row3.setHeightInPoints((short) 50);
	        String[] headers = {"序號", "日期", "所屬車間", "項(xiàng)目號", "機(jī)臺(tái)", "模號", "任務(wù)包編碼", "任務(wù)包名稱", "入庫數(shù)量", "實(shí)收數(shù)", "班", "組", "組員", "備注"};
	        for (int i = 0; i < headers.length; i++) {
	            Cell cell = row3.createCell(i);
	            cell.setCellValue(headers[i]);
	            cell.setCellStyle(headerStyle);
	        }
	
	        // 第4行及以后:數(shù)據(jù)行
	        for (int i = 0; i < data.size(); i++) {
	            StockInEntity item = data.get(i);
	            Row row = sheet.createRow(3 + i);
	            row.setHeightInPoints((short) 45);
	
	            // 序號
	            Cell cell0 = row.createCell(0);
	            cell0.setCellValue(i + 1);
	            cell0.setCellStyle(contentStyle);
	
	            // 日期
	            Cell cell11 = row.createCell(1);
	            cell11.setCellValue(item.getCreateTime().format(formatter));
	            cell11.setCellStyle(contentStyle);
	
	            // 所屬車間
	            Cell cell2 = row.createCell(2);
	            cell2.setCellValue(item.getReceiveDeptName());
	            cell2.setCellStyle(contentStyle);
	
	            // 項(xiàng)目號
	            Cell cell3 = row.createCell(3);
	            cell3.setCellValue(item.getProjectNumber());
	            cell3.setCellStyle(contentStyle);
	
	            // 機(jī)臺(tái)
	            Cell cell4 = row.createCell(4);
	            cell4.setCellValue(item.getMachine());
	            cell4.setCellStyle(contentStyle);
	
	            // 模號
	            Cell cell5 = row.createCell(5);
	            cell5.setCellValue(item.getModelNo());
	            cell5.setCellStyle(contentStyle);
	
	            // 任務(wù)包編碼
	            Cell cell6 = row.createCell(6);
	            cell6.setCellValue(item.getMaterialCode());
	            cell6.setCellStyle(contentStyle);
	
	            // 任務(wù)包名稱
	            Cell cell7 = row.createCell(7);
	            cell7.setCellValue(item.getMaterialName());
	            cell7.setCellStyle(contentStyle);
	
	            // 入庫數(shù)量
	            Cell cell8 = row.createCell(8);
	            cell8.setCellValue(String.valueOf(item.getQty()));
	            cell8.setCellStyle(contentStyle);
	
	            // 實(shí)收數(shù)
	            Cell cell9 = row.createCell(9);
	            cell9.setCellValue(String.valueOf(item.getQty()));
	            cell9.setCellStyle(contentStyle);
	
	            // 班、組、組員、備注(示例中為空,可根據(jù)實(shí)際數(shù)據(jù)填充)
	            for (int j = 10; j < 14; j++) {
	                Cell cell = row.createCell(j);
	                cell.setCellStyle(contentStyle);
	            }
	        }
	    }
    }

2、使用示例(Web 場景)

在 Controller 中調(diào)用工具類,導(dǎo)出 Excel:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

@RestController
public class ExportController {

    /**
     * 生產(chǎn)入庫單導(dǎo)出
     */
    @PostMapping("/exportProInput")
    public void exportProInput(HttpServletResponse response, InputQueryDTO input) {
        List<StockInEntity> list = baseService.selectProInput(input);
        PaAssert.isError(CollUtil.isEmpty(list), "導(dǎo)出數(shù)據(jù)不能為空");
        try {
            // 設(shè)置響應(yīng)頭
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String fileName = URLEncoder.encode("入庫單.xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            // 導(dǎo)出Excel
            OutputStream outputStream = response.getOutputStream();
            baseService.exportWarehouseInExcel(outputStream, list);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            throw new BaseException("導(dǎo)出失敗");
        }
    }

    // 模擬數(shù)據(jù)(實(shí)際從數(shù)據(jù)庫查詢)
    private List<StockInEntity> getWarehouseInData() {
        // 示例數(shù)據(jù),實(shí)際替換為業(yè)務(wù)數(shù)據(jù)
        StockInEntity= new StockInEntity();
        item1.setProjectNo("GPC25061095B2");
        item1.setDate("2025/12/16");
        item1.setWorkshop("精密裝配");
        item1.setMachine("J20-04");
        item1.setModel("5400002400");
        item1.setTaskCode("導(dǎo)向壓銷部件2");
        item1.setTaskName("導(dǎo)向壓銷部件2");
        item1.setInQty(2);
        item1.setActualQty(2);

        // 可添加更多數(shù)據(jù)...
        return List.of(item1, item1); // 示例中重復(fù)添加,實(shí)際替換為真實(shí)數(shù)據(jù)
    }
}

四、導(dǎo)出效果

總結(jié)

  1. Sheet 分組邏輯:通過projectNo.substring(0, projectNo.length() - 2)截取項(xiàng)目號前綴,實(shí)現(xiàn)同一前綴的記錄分到同一個(gè) Sheet。
  2. 格式還原:通過單元格合并、樣式設(shè)置(背景色、邊框、對齊方式)還原示例中的Excel 格式。
  3. 動(dòng)態(tài)數(shù)據(jù):代碼中 “填單日期、交付批次、單號” 為固定值,實(shí)際應(yīng)從業(yè)務(wù)數(shù)據(jù)中動(dòng)態(tài)獲?。稍趯?shí)體類中添加對應(yīng)字段)。

到此這篇關(guān)于Java實(shí)現(xiàn)Excel導(dǎo)出的全部流程(多Sheet、復(fù)雜格式)的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)Excel導(dǎo)出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?8?Stream?處理數(shù)據(jù)方法匯總

    Java?8?Stream?處理數(shù)據(jù)方法匯總

    這篇文章主要介紹了Java?8?Stream處理數(shù)據(jù),Stream是Java?8?新引入的一個(gè)包它讓我們能用聲明式的方式處理數(shù)據(jù),Stream流式處理相較于傳統(tǒng)方法簡潔高效,也便于進(jìn)行并發(fā)編程,更多相關(guān)內(nèi)容需要的小伙伴可以參考下面文章內(nèi)容
    2022-06-06
  • SpringBoot使用阿里oss實(shí)現(xiàn)文件上傳的流程步驟

    SpringBoot使用阿里oss實(shí)現(xiàn)文件上傳的流程步驟

    云服務(wù)指的就是通過互聯(lián)網(wǎng)對外提供的各種各樣的服務(wù),比如像:語音服務(wù)、短信服務(wù)、郵件服務(wù)、視頻直播服務(wù)、文字識別服務(wù)、對象存儲(chǔ)服務(wù)等等,本文通過代碼示例和圖文給大家介紹了SpringBoot使用阿里oss實(shí)現(xiàn)文件上傳的流程步驟,需要的朋友可以參考下
    2025-01-01
  • 深入理解 Java注解及實(shí)例

    深入理解 Java注解及實(shí)例

    這篇文章主要介紹了深入理解 Java注解及實(shí)例的相關(guān)資料,希望通過本文大家能夠掌握java注解的知識,需要的朋友可以參考下
    2017-09-09
  • springboot統(tǒng)一返回json數(shù)據(jù)格式并配置系統(tǒng)異常攔截方式

    springboot統(tǒng)一返回json數(shù)據(jù)格式并配置系統(tǒng)異常攔截方式

    這篇文章主要介紹了springboot統(tǒng)一返回json數(shù)據(jù)格式并配置系統(tǒng)異常攔截方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • MyBatis動(dòng)態(tài)SQL之<choose><when><o(jì)therwise>標(biāo)簽的使用

    MyBatis動(dòng)態(tài)SQL之<choose><when><o(jì)therwise>標(biāo)簽的使用

    MyBatis中動(dòng)態(tài)語句choose-when-otherwise 類似于Java中的switch-case-default語句,本文就來介紹一下MyBatis動(dòng)態(tài)SQL之<choose><when><o(jì)therwise>標(biāo)簽的使用,感興趣的可以了解一下
    2023-09-09
  • javaWeb傳收參數(shù)方式總結(jié)示例分析

    javaWeb傳收參數(shù)方式總結(jié)示例分析

    這篇文章主要為大家介紹了javaWeb傳收參數(shù)方式總結(jié)示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Java日期工具類時(shí)間校驗(yàn)實(shí)現(xiàn)

    Java日期工具類時(shí)間校驗(yàn)實(shí)現(xiàn)

    一般項(xiàng)目中需要對入?yún)⑦M(jìn)行校驗(yàn),比如必須是一個(gè)合法的日期,本文就來介紹一下Java日期工具類時(shí)間校驗(yàn)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • JDK25模塊導(dǎo)入聲明的實(shí)現(xiàn)步驟

    JDK25模塊導(dǎo)入聲明的實(shí)現(xiàn)步驟

    本文主要介紹了JDK25模塊導(dǎo)入聲明的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • JAVA二叉樹的幾種遍歷(遞歸,非遞歸)實(shí)現(xiàn)

    JAVA二叉樹的幾種遍歷(遞歸,非遞歸)實(shí)現(xiàn)

    這篇文章主要介紹了JAVA二叉樹的幾種遍歷(遞歸,非遞歸)實(shí)現(xiàn),需要的朋友可以參考下
    2020-12-12
  • 如何基于http代理解決Java固定ip問題

    如何基于http代理解決Java固定ip問題

    這篇文章主要介紹了如何基于http代理解決Java固定ip問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評論

瓮安县| 太原市| 容城县| 威信县| 南投市| 曲靖市| 和平县| 离岛区| 青川县| 卢龙县| 营口市| 峨眉山市| 张北县| 龙山县| 敦煌市| 石楼县| 嵩明县| 兴义市| 石阡县| 揭阳市| 毕节市| 吉首市| 沅陵县| 贵州省| 荔波县| 临邑县| 平阴县| 聊城市| 青阳县| 桓台县| 阜宁县| 宜兰县| 白河县| 额敏县| 大邑县| 巴东县| 竹山县| 衢州市| 区。| 德江县| 公安县|