合併單元格的方法:
指定 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();
}
}
效果圖