Java使用POI操作Excel,判斷標誌列如果相同,則合併多組單元格

合併單元格的方法:
指定 4 個參數,起始行,結束行,起始列,結束列。然後這個區域將被合併。

每種材料有四個屬性:

  • displayCode  代號
  • practName    名稱
  • areaName     地區
  • price              價格

需求:根據“displayCode ”判斷是否是同一種材料,如果是同一種材料,則合併"displayCode"和"practName ",因爲材料所在地和價格各地區都有不同,不合並

代碼

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;

public class TestExcel {

    public static void main(String[] args) throws IOException {
        //構建測試數據
		List<Map<String, String>> searchDataList = new ArrayList<>();
		Map<String, String> myMap = new HashMap<>();
		myMap.put("displayCode", "1001001");
		myMap.put("practName", "砂石");
		myMap.put("areaName", "湖南");
		myMap.put("price", "19");
		searchDataList.add(myMap);
		myMap = new HashMap<>();
		myMap.put("displayCode", "1001001");
		myMap.put("practName", "砂石");
		myMap.put("areaName", "河北");
		myMap.put("price", "20");
		searchDataList.add(myMap);
		myMap = new HashMap<>();
		myMap.put("displayCode", "1001002");
		myMap.put("practName", "水泥");
		myMap.put("areaName", "江蘇");
		myMap.put("price", "21");
		searchDataList.add(myMap);
		myMap = new HashMap<>();
		myMap.put("displayCode", "1001003");
		myMap.put("practName", "混凝土");
		myMap.put("areaName", "北京");
		myMap.put("price", "22");
		searchDataList.add(myMap);
		myMap = new HashMap<>();
		myMap.put("displayCode", "1001004");
		myMap.put("practName", "砂礫");
		myMap.put("areaName", "四川");
		myMap.put("price", "23");
		searchDataList.add(myMap);
		myMap = new HashMap<>();
		myMap.put("displayCode", "1001004");
		myMap.put("practName", "砂礫");
		myMap.put("areaName", "內蒙古");
		myMap.put("price", "24");
		searchDataList.add(myMap);
		SXSSFWorkbook wb=new SXSSFWorkbook(500);
			
		//標題格式
		XSSFCellStyle ztStyle0 = (XSSFCellStyle) wb.createCellStyle(); 
		 
       // 創建單元格樣式對象   
       XSSFCellStyle ztStyle = (XSSFCellStyle) wb.createCellStyle();   
       Font ztFont = wb.createFont();   
       ztFont.setFontHeightInPoints((short)9);    // 將字體大小設置爲18px   
       ztFont.setFontName("宋體");  
       ztStyle.setFont(ztFont);                    // 將字體應用到樣式上面   

       // 設置單元格內容水平對其方式   
       ztStyle.setAlignment(HorizontalAlignment.CENTER);   
       // 設置單元格內容垂直對其方式   
       ztStyle.setVerticalAlignment(VerticalAlignment.CENTER); 
       ztStyle.setVerticalAlignment(VerticalAlignment.CENTER);   
       ztStyle.setWrapText(true);                     // 設置單元格內容是否自動換行   
       
       // 創建單元格樣式對象   
       XSSFCellStyle ztStyle2 = (XSSFCellStyle) wb.createCellStyle();   
       ztStyle2.setFont(ztFont);                    // 將字體應用到樣式上面   

       // 設置單元格內容水平對其方式   
       ztStyle2.setAlignment(HorizontalAlignment.LEFT);   
       // 設置單元格內容垂直對其方式   
       ztStyle2.setVerticalAlignment(VerticalAlignment.CENTER); 
       ztStyle2.setVerticalAlignment(VerticalAlignment.CENTER);   
       ztStyle2.setWrapText(true); // 設置單元格內容是否自動換行   
       
	    Sheet sheet=wb.createSheet("合併測試");
		Row row=sheet.createRow(0);
		Cell cell=row.createCell(0, CellType.STRING);
		cell.setCellValue("代號");
		sheet.setColumnWidth(0, 3000);
		cell.setCellStyle(ztStyle);
		cell = row.createCell(1, CellType.STRING);
		cell.setCellValue("名稱");
		sheet.setColumnWidth(1, 5000);
		cell.setCellStyle(ztStyle);
		cell = row.createCell(2, CellType.STRING);
		cell.setCellValue("所在地");
		sheet.setColumnWidth(2, 10000);
		cell.setCellStyle(ztStyle);
		cell = row.createCell(3, CellType.STRING);
		cell.setCellValue("單價");
		sheet.setColumnWidth(3, 3000);
		cell.setCellStyle(ztStyle);
		
		if(searchDataList != null && searchDataList.size() > 0 )  {
			int n = 1 ;
			Map<Map<String, String>,Row> rowMap = new LinkedHashMap<>();
			//{0=代號, 1=材料名稱, 2=所在地, 4=單價}
			Map<String, String> map = null;
            //key爲displayCode,value爲displayCode相同的個數有多少個
			Map<String,Integer> sameCountMap = new HashMap<>();
            //key爲displayCode,value爲第一個代號爲該displayCode的初始的行的索引號
			Map<String,Integer> startDisplayCodeMap = new HashMap<>();
			Integer count = null;
			String prevDisplayCode = null;
			String displayCode = null;
			Integer startRowIndex = null;
			for(int i = 0 ; i < searchDataList.size() ; i ++ ) {
				
				map = searchDataList.get(i);
				displayCode = map.get("displayCode");
				map = searchDataList.get(i);
				//代號
				row=sheet.createRow(n); 
				cell = row.createCell(0, CellType.STRING);
				cell.setCellValue(displayCode);
				cell.setCellStyle(ztStyle);
				//材料名稱
				cell = row.createCell(1, CellType.STRING);
				cell.setCellValue(map.get("practName"));
				cell.setCellStyle(ztStyle2);
				//所在地
				cell = row.createCell(2, CellType.STRING);
				cell.setCellValue(map.get("areaName"));
				cell.setCellStyle(ztStyle2);
				//單價
				cell = row.createCell(3, CellType.STRING);
				cell.setCellValue(map.get("price"));
				cell.setCellStyle(ztStyle);
				rowMap.put(map, row);
				
				//合併行
				count = sameCountMap.get(displayCode);
				if(count == null) {
					count = 0;
					startDisplayCodeMap.put(displayCode, n);
				}
				count++;
				sameCountMap.put(displayCode, count);
				if(prevDisplayCode != null && !prevDisplayCode.equals(displayCode)) {
					startRowIndex = startDisplayCodeMap.get(prevDisplayCode);//獲取該代號的初始行位置
					count = sameCountMap.get(prevDisplayCode);//獲取相同代號總共有多少行
					if(count > 1) {
						sheet.addMergedRegion(new CellRangeAddress(startRowIndex, startRowIndex+count-1, 0, 0));//合併代號行
						sheet.addMergedRegion(new CellRangeAddress(startRowIndex, startRowIndex+count-1, 1, 1));//合併工料機名稱行
					}
				}else if(i == searchDataList.size() - 1){
					//最後一行
					startRowIndex = startDisplayCodeMap.get(displayCode);//獲取該代號的初始行位置
					count = sameCountMap.get(displayCode);//獲取相同代號總共有多少行
					if(count > 1) {
						sheet.addMergedRegion(new CellRangeAddress(startRowIndex, startRowIndex+count-1, 0, 0));//合併代號行
						sheet.addMergedRegion(new CellRangeAddress(startRowIndex, startRowIndex+count-1, 1, 1));//合併名稱行
					}
				}
				prevDisplayCode = displayCode;
				n++;
			}
		}
        File file = new File("E:\\demo.xlsx");
        FileOutputStream fout = new FileOutputStream(file);
        wb.write(fout);
        fout.close();
    }

}

效果圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章