JavaはPOIに基づいてセルを動的にマージします

poi に基づいてテーブルを動的にマージする

-まずエフェクトダイアグラムを見てください.
ここに画像の説明を挿入
左側がメインテーブルデータで,右側がサブテーブルデータです.必要に応じて変更できます.以下のコードを見てみましょう.

  • 依存関係を導入する
		<!--poi-->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>4.1.0</version>
		</dependency>
  • PoiExcel クラスを作成する

最初にデータを構築します.テーブルによると,メインテーブルとサブテーブルは関連しているので,メインテーブルとサブテーブルのデータはマップコレクションに格納されます.メインテーブルの値はマップのキーとして使用されます. 、値はサブテーブルのリスト コレクションに対応します。次のコードを参照できます。

        String[] masterHead = {
    
    "学号","姓名","专业"};
        String[] childHead = {
    
    "课程名称","上课地点","任课教师","上课时间"};
        List<String[]> childList = new ArrayList<>();
        childList.add(new String[]{
    
    "Java程序设计","1号楼302","雷老师","2022/8/30 15:53:49"});
        childList.add(new String[]{
    
    "数据结构","1号楼305","雷老师","2022/8/30 9:18:28"});
        List<String[]> childList1 = new ArrayList<>();
        childList1.add(new String[]{
    
    "计算机网络","2号楼301","方老师","2022/8/30 15:53:49"});
        List<Map<String,List<String[]>>> masterList = new ArrayList<>();
        Map<String,List<String[]>> map = new HashMap();
        map.put("20210211-张晓-计算机与科学",childList);
        map.put("20210212-于丽-电子信息工程",childList1);
        masterList.add(map);

次に、Excel ブック オブジェクトを作成します。

 		//创建Excel工作薄对象
        HSSFWorkbook workbook=new HSSFWorkbook();
        //创建Excel工作表对象
        HSSFSheet sheet = workbook.createSheet("wj");
        //设置单元格居中
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);

次に、要件に従って行ごとにワークシートにデータを入力します。最初は複雑なヘッダー、最初の行はメイン テーブルとサブテーブル、メイン テーブルとサブテーブルはマージされた列で、長さに従って決定されます。メインおよびサブテーブル ヘッダー、マージされた列の数; 2 行目はヘッダーで、メインおよびサブ ヘッダーの配列に従って入力されます。

		//创建行的单元格,从0开始
        HSSFRow row = sheet.createRow(0);

        //创建统计单元格
        HSSFCell masterCell=row.createCell(0);
        //赋值
        masterCell.setCellValue("主表");
        masterCell.setCellStyle(cellStyle);
        //合并列
        CellRangeAddress region=new CellRangeAddress(0, 0, 0, masterHead.length-1);
        sheet.addMergedRegion(region);

        //创建详情单元格  从统计单元格的后一格开始创建
        HSSFCell childCell = row.createCell(masterHead.length);
        //赋值
        childCell.setCellValue("子表");
        childCell.setCellStyle(cellStyle);
        //合并列
        region=new CellRangeAddress(0, 0, masterHead.length, masterHead.length+childHead.length-1);
        sheet.addMergedRegion(region);

        //表头 从1开始
        HSSFRow titleRow = sheet.createRow(1);
        //主表头
        for (int i = 0; i < masterHead.length ; i++) {
    
    
            HSSFCell msCell = titleRow.createCell(i);
            msCell.setCellStyle(cellStyle);
            msCell.setCellValue(masterHead[i]);
        }
        //子表头
        for (int i = 0; i < childHead.length; i++) {
    
    
            HSSFCell chcell = titleRow.createCell(masterHead.length+i);
            chcell.setCellStyle(cellStyle);
            chcell.setCellValue(childHead[i]);
        }

このように、1行目と2行目のヘッダーを埋めてから、対応するデータを埋めていきます.メインテーブルを先に埋めていきます.メインテーブルの値を区切るのに「-」を使っているので、文字列を配列に切り出し、主テーブルのデータと対応する副テーブルのデータを取得するワークブックの最初の2行はヘッダーなので、3行目からデータを埋めるため、行の添え字は2、次に 3 番目から 行を作成し、メイン テーブルにデータを入力します. 充填するときは、サブ テーブルのリストのサイズを判断する必要があります. 1 より大きい場合は、それをマージする必要があります. 充填後メイン テーブル, サブテーブルを埋める必要があります. サブテーブルをマージする必要はありません. 行ごとに埋めるだけです. コードは以下のように表示されます:

        //填充数据
        int lastRowIndex = 2; //记录最后行位置
        for (Map<String,List<String[]>> m : masterList){
    
    
            for (String key : m.keySet()){
    
    
                String[] ms = key.split("-");
                List<String[]> chlist = m.get(key);
                HSSFRow valueRow = sheet.createRow(lastRowIndex);
                for (int i = 0; i < ms.length ; i++) {
    
    
                    HSSFCell mscell = valueRow.createCell(i);
                    mscell.setCellStyle(cellStyle);
                    mscell.setCellValue(ms[i]);
                    if (chlist.size()>1){
    
     //子表数量大于1才进行 行合并
                        region=new CellRangeAddress(lastRowIndex, lastRowIndex+chlist.size()-1, i, i);
                        sheet.addMergedRegion(region);
                    }
                }
                for (int i = 0; i < chlist.size(); i++) {
    
    
                    String[] chstrs = chlist.get(i);
                    HSSFRow chRow;
                    if (i == 0){
    
     //避免重复创建 覆盖主表数据
                        chRow = valueRow;
                    }else {
    
    
                        chRow  = sheet.createRow(lastRowIndex);
                    }
                    lastRowIndex++;
                    for (int j = 0; j < chstrs.length; j++) {
    
    
                        HSSFCell chcell = chRow.createCell(ms.length+j);
                        chcell.setCellStyle(cellStyle);
                        chcell.setCellValue(chstrs[j]);
                    }
                }
            }
        }

最も重要なコード行は次のとおりです。

new CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)

このコードは、セルを結合するためのものです。パラメーター 1: 行の開始パラメーター 2: 行の終了パラメーター 3: 列の開始パラメーター 4: 列の終了

  • 最後に、PoiExcel クラスの完全なコードを見てください。

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;

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

/**
 * @author huao
 * @Date 2022/8/31 13:50
 * @description:
 */
public class PoiExcel {
    
    

    public static void excelport(HttpServletResponse response) throws Exception {
    
    

        //数据来源 通过参数传入
        String[] masterHead = {
    
    "学号","姓名","专业"};
        String[] childHead = {
    
    "课程名称","上课地点","任课教师","上课时间"};
        List<String[]> childList = new ArrayList<>();
        childList.add(new String[]{
    
    "Java程序设计","1号楼302","雷老师","2022/8/30 15:53:49"});
        childList.add(new String[]{
    
    "数据结构","1号楼305","雷老师","2022/8/30 9:18:28"});
        List<String[]> childList1 = new ArrayList<>();
        childList1.add(new String[]{
    
    "计算机网络","2号楼301","方老师","2022/8/30 15:53:49"});
        List<Map<String,List<String[]>>> masterList = new ArrayList<>();
        Map<String,List<String[]>> map = new HashMap();
        map.put("20210211-张晓-计算机与科学",childList);
        map.put("20210212-于丽-电子信息工程",childList1);
        masterList.add(map);

        //创建Excel工作薄对象
        HSSFWorkbook workbook=new HSSFWorkbook();
        //创建Excel工作表对象
        HSSFSheet sheet = workbook.createSheet("wj");
        //设置单元格居中
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);

        //创建行的单元格,从0开始
        HSSFRow row = sheet.createRow(0);

        //创建统计单元格
        HSSFCell masterCell=row.createCell(0);
        //赋值
        masterCell.setCellValue("主表");
        masterCell.setCellStyle(cellStyle);
        //合并列
        CellRangeAddress region=new CellRangeAddress(0, 0, 0, masterHead.length-1);
        sheet.addMergedRegion(region);

        //创建详情单元格  从统计单元格的后一格开始创建
        HSSFCell childCell = row.createCell(masterHead.length);
        //赋值
        childCell.setCellValue("子表");
        childCell.setCellStyle(cellStyle);
        //合并列
        region=new CellRangeAddress(0, 0, masterHead.length, masterHead.length+childHead.length-1);
        sheet.addMergedRegion(region);

        //表头 从1开始
        HSSFRow titleRow = sheet.createRow(1);
        //主表头
        for (int i = 0; i < masterHead.length ; i++) {
    
    
            HSSFCell msCell = titleRow.createCell(i);
            msCell.setCellStyle(cellStyle);
            msCell.setCellValue(masterHead[i]);
        }
        //子表头
        for (int i = 0; i < childHead.length; i++) {
    
    
            HSSFCell chcell = titleRow.createCell(masterHead.length+i);
            chcell.setCellStyle(cellStyle);
            chcell.setCellValue(childHead[i]);
        }

        //填充数据
        int lastRowIndex = 2; //记录最后行位置
        for (Map<String,List<String[]>> m : masterList){
    
    
            for (String key : m.keySet()){
    
    
                String[] ms = key.split("-");
                List<String[]> chlist = m.get(key);
                HSSFRow valueRow = sheet.createRow(lastRowIndex);
                for (int i = 0; i < ms.length ; i++) {
    
    
                    HSSFCell mscell = valueRow.createCell(i);
                    mscell.setCellStyle(cellStyle);
                    mscell.setCellValue(ms[i]);
                    if (chlist.size()>1){
    
     //子表数量大于1才进行 行合并
                        region=new CellRangeAddress(lastRowIndex, lastRowIndex+chlist.size()-1, i, i);
                        sheet.addMergedRegion(region);
                    }
                }
                for (int i = 0; i < chlist.size(); i++) {
    
    
                    String[] chstrs = chlist.get(i);
                    HSSFRow chRow;
                    if (i == 0){
    
     //避免重复创建 覆盖主表数据
                        chRow = valueRow;
                    }else {
    
    
                        chRow  = sheet.createRow(lastRowIndex);
                    }
                    lastRowIndex++;
                    for (int j = 0; j < chstrs.length; j++) {
    
    
                        HSSFCell chcell = chRow.createCell(ms.length+j);
                        chcell.setCellStyle(cellStyle);
                        chcell.setCellValue(chstrs[j]);
                    }
                }
            }
        }

        String fileName = URLEncoder.encode("POIExcel下载测试","UTF-8");
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+fileName+".xls");
        OutputStream os = response.getOutputStream();
        workbook.write(os);
        os.flush();
        os.close();
        workbook.close();
    }
}

次に、コントローラー層のコード:

import com.example.demo.utils.PoiExcel;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

/**
 * @author huao
 * @Date 2022/8/31 13:56
 * @description:
 */
@RestController
@RequestMapping("/demo")
public class DemoWeb {
    
    

    @RequestMapping("/download")
    public void download(HttpServletResponse response) throws Exception {
    
    
        PoiExcel.excelport(response);
    }
}

依存関係をインポートした後、コードをコピーして直接使用できます。

執筆理由 インターネットでセルを動的に結合する例をたくさん見ましたが、すべてを理解することはできませんでした. 多分私はそれが得意すぎて、自分で作成しました. コードの量は非常に少ないです.不明な点はありません。コメントを歓迎します。メッセージまたはプライベートメッセージを残してください。

おすすめ

転載: blog.csdn.net/qq_44874270/article/details/126636778