首先展示出來的效果圖,避免浪費大家查找的時間
效果如上;前後列合併,中間列不合並
代碼如下:
方法參數: List<OrderExcl> orders, 一行記錄對應一個類
XSSFWorkbook wb = new XSSFWorkbook();
//sheet的名字
XSSFSheet sheet = wb.createSheet("訂單列表");
//設置默認列寬和行高
sheet.setDefaultColumnWidth((short) 20);
sheet.setDefaultRowHeightInPoints(20);
//標題行,第0行數據,就是圖片上的藍色行
XSSFRow row = sheet.createRow(0);
String[] str = {"業務員", "客戶姓名", "客戶電話",........};
// 第一行
Field[] declaredFields = orderCondition.getClass().getDeclaredFields();
OutputStream out = null;
try {
//設置樣式
XSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(HSSFColor.ROYAL_BLUE.index);
//第一行數據
for (int i = 0; i < str.length; i++) {
//填充背景顏色
row.createCell(i).setCellStyle(cellStyle);
row.getCell(i).setCellValue(str[i]);
}
//拿出所有的數據
Iterator<OrderExcl> iterator = orders.iterator();
//一條數據就是一行記錄,開始起始的行號
int index = 1;
while (iterator.hasNext()) {
//這個作用是爲了記錄需要合併的行的起始行
int temp = index;
OrderExcl order = iterator.next();
List<Goods> goods = order.getGoods();
int num = 0;
if (null != goods && goods.size() > 0) {
num += goods.size();
}
//合併行的結束行號
index += num;
//獲取所有的屬/性名
Class orderClass = order.getClass();
Field[] fields = orderClass.getDeclaredFields();
//以不需要合併行的個數,作爲需要創建的行數
for (int e = 0; e < num; e++) {
XSSFRow sheetRow = sheet.createRow(temp + e);
for (int i = 0; i < fields.length; i++) {
//填充不需要合併列的數據信息 start
if (i == 23) {
String name = goods.get(e).getShpMingCheng() == null ? "" : goods.get(e).getShpMingCheng();
sheetRow.createCell(24).setCellValue(name);
continue;
}
if (i == 24) {
String code = goods.get(e).getShpBianMa() == null ? "" : goods.get(e).getShpBianMa();
sheetRow.createCell(23).setCellValue(code);
continue;
}
if (i == 25) {
String weight = goods.get(e).getZhlKg() == null ? "" : goods.get(e).getZhlKg().toString();
sheetRow.createCell(25).setCellValue(weight);
continue;
}
//填充不需要合併列的數據信息 end
//填充需要合併行的單元格的信息
XSSFCell cell = sheetRow.createCell(i);
//獲取字段屬性的值
String fieldName = fields[i].getName();
Object result = "";
//這裏是你不需要合併的單元格里面需要填充的數據集合的名字
if (!fieldName.equals("goods")) {
result = getResult(order, fieldName);
}
if (fieldName.equals("orderDate")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
result = result == null ? "" : simpleDateFormat.format((Date) result);
}
result = result == null ? "" : result.toString();
XSSFRichTextString richString = new XSSFRichTextString(result.toString());
cell.setCellValue(richString);
}
//合併單元格
if (e == num - 1) {
/**
23代表的意思是並不需要合併的列的 起始列號+ 1 ;
比如:我的第 6列需要合併列的起始位置,則此處寫 7
*/
for (int j = 0; j < 23; j++) {
//行號 行號 列號 列號
sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
}
/**
29代表的意思是並不需要合併的列的 結束列號+ 1 ;
比如:我的第 16列需要合併列的結束位置,則此處寫 17
*/
for (int j = 29; j < fields.length; j++) {
sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
}
}
}//輸出到本
try{地
OutputStream o = new FileOutputStream("D://2007.xlsx");
workbook.write(o);
}catch (Exception e) {
e.printStackTrace();
} finally {
if (o!= null) {
o.close();
}
}
/**
*反射 調用get方法,獲取屬性對應的值
*
* @param fieldName
* @return
*/
public Object getResult(OrderExcl order, String fieldName) {
try {
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Class tCls = order.getClass();
Method getMethod = tCls.getMethod(getMethodName, new Class[]{});
Object value = getMethod.invoke(order, new Object[]{});
return value;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
注意事項
保證實體類的字段和起始行的字段順序一致,否則導出的顯示順序不一致
上面的方法實現了業務需要;獻給大家借鑑;後面我會抽取一個工具類;方便大家直接使用;