概述
首先展示出来的效果图,避免浪费大家查找的时间
效果如上;前后列合并,中间列不合并
代码如下:
方法参数: 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;
}
注意事项
保证实体类的字段和起始行的字段顺序一致,否则导出的显示顺序不一致
上面的方法实现了业务需要;献给大家借鉴;后面我会抽取一个工具类;方便大家直接使用;
========工具类
里面的枚举类,判断需要根据自己公司的枚举类修改取值即可
public class ExclUtils {
/**
* 不需要合并单元格的
*
* @param data 行数据的集合
* @param heardStyle 开始行的单元格样式
* @param otherStyle 除标题行的其他需要设置样式的单元格;key:属性名=字段名 value:填充的样式;
* @param sheetName sheet的名字
* @param headers 标题行的数据信息
* @param columnWidth 设置默认宽度
* @param rowHeight 设置默认行高
* @param dateFormat 日期格式化
* @param <T> 行数据信息
* @return
* @throws IllegalAccessException
*/
public static <T> XSSFWorkbook needNotMerge(List<T> data,
XSSFCellStyle heardStyle,
Map<String, XSSFCellStyle> otherStyle,
String sheetName, String[] headers,
Short columnWidth,
Short rowHeight,
String dateFormat
) throws IllegalAccessException, NoSuchFieldException {
XSSFWorkbook wb = setDefaultConfig(sheetName,
columnWidth, rowHeight, heardStyle, headers);
XSSFSheet sheet = wb.getSheetAt(0);
//填充数据行
Iterator<T> iterator = data.iterator();
int index = 0;
if (null != headers) {
index = 1;
}
while (iterator.hasNext()) {
XSSFRow row = sheet.createRow(index);
T next = iterator.next();
Class<?> aClass = next.getClass();
Field[] fields = aClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
field.setAccessible(true);
Object value = field.get(next);
if (null == value) {
value = "";
}
value = formatDataToString(dateFormat, value);
if (null != otherStyle) {
boolean flag = otherStyle.containsKey(field.getName());
if (flag) {
row.createCell(i).setCellStyle(otherStyle.get(field.getName()));
row.getCell(i).setCellValue(value.toString());
}
}
row.createCell(i).setCellValue(value.toString());
}
index++;
}
return wb;
}
/**
* @param data 行数据的集合
* @param heardStyle 头样式
* @param otherStyle 其他行样式;key:属性值 value:样式
* @param sheetName sheet名字
* @param headers 标题数组
* @param columnWidth 单元格列宽
* @param rowHeight 行高
* @param needNotMergerColumNum 不需要合并的列的属性名,以及对应的列号;key:列号 value:属性名
* @param dateFormat 日期格式
* @param mergeName
* @param <T> 行数据对象
* @param <E> 不需要合并的单元格数据对象
* @return
*/
public static <T, E> XSSFWorkbook rowMerge(List<T> data,
XSSFCellStyle heardStyle,
Map<String, XSSFCellStyle> otherStyle,
String sheetName,
String[] headers,
Short columnWidth,
Short rowHeight,
Map<Integer, String> needNotMergerColumNum,
String dateFormat,
Integer start,
Integer end,
String mergeName
) throws Exception {
XSSFWorkbook wb = setDefaultConfig(sheetName, columnWidth,
rowHeight, heardStyle, headers);
XSSFSheet sheet = wb.getSheetAt(0);
//填充数据行
Iterator<T> iterator = data.iterator();
int index = 0;
if (null != headers) {
index = 1;
}
while (iterator.hasNext()) {
int temp = index;
T next = iterator.next();
Field mergeField = next.getClass().getDeclaredField(mergeName);
mergeField.setAccessible(true);
List<E> mergeData = (List<E>) mergeField.get(next);
if (null == mergeData || mergeData.size() < 1) {
Object o = new Object();
E e = (E) o;
mergeData.add(e);
}
index += mergeData.size();
Field[] fields = next.getClass().getDeclaredFields();
for (int i = 0; i < mergeData.size(); i++) {
XSSFRow row = sheet.createRow(temp + i);
for (int j = 0; j < fields.length; j++) {
Field field = fields[j];
field.setAccessible(true);
String fileName = field.getName();
XSSFCell cell = row.createCell(j);
if (null != otherStyle && otherStyle.containsKey(fileName)) {
cell.setCellStyle(otherStyle.get(fileName));
}
if (needNotMergerColumNum.containsKey(j)) {
String mergeFieldName = needNotMergerColumNum.get(j);
try {
Field mergeDeclaredField = mergeData.get(i).getClass().getDeclaredField(mergeFieldName);
mergeDeclaredField.setAccessible(true);
Object value = mergeDeclaredField.get(mergeData.get(i));
if (null == value) {
value = "";
}
value = formatDataToString(dateFormat, value);
cell.setCellValue(value.toString());
continue;
} catch (Exception e) {
cell.setCellValue("");
continue;
}
}
//获取属性字段的值
Object o = field.get(next);
if (null == o) {
o = "";
}
o = formatDataToString(dateFormat, o);
cell.setCellValue(o.toString());
}
//合并单元格
if (i == mergeData.size() - 1) {
for (int j = 0; j < start; j++) {
//行号 行号 列号 列号
sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
}
for (int j = end; j < fields.length; j++) {
sheet.addMergedRegion(new CellRangeAddress(temp, index - 1, j, j));
}
}
}
}
return wb;
}
/**
* excl的默认设置
*
* @param sheetName sheet名字
* @param columnWidth 列宽
* @param rowHeight 行高
* @param heardStyle 头样式
* @param headers 标题行
*/
private static XSSFWorkbook setDefaultConfig(String sheetName, Short columnWidth,
Short rowHeight, XSSFCellStyle heardStyle, String[] headers) {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet(sheetName);
if (null != columnWidth) {
sheet.setDefaultColumnWidth(columnWidth);
} else {
sheet.setDefaultColumnWidth((short) 20);
}
if (null != rowHeight) {
sheet.setDefaultRowHeightInPoints(rowHeight);
} else {
sheet.setDefaultRowHeightInPoints(20);
}
if (null != headers) { //创建标题行
XSSFRow headerRow = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
if (null != heardStyle) {
headerRow.createCell(i).setCellStyle(heardStyle);
headerRow.getCell(i).setCellValue(headers[i]);
} else {
headerRow.createCell(i).setCellValue(headers[i]);
}
}
}
return wb;
}
/**
* 日期和枚举类转化为字符串
*
* @param dateFormat 日期格式,默认 yyyy-MM-dd HHLmm
* @param value 需要转字符串的对象
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public static String formatDataToString(String dateFormat, Object value) throws NoSuchFieldException, IllegalAccessException {
if (null == value) {
return "";
}
if (null == dateFormat) {
dateFormat = "yyyy-MM-dd HH:mm";
}
if (value instanceof Date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
value = simpleDateFormat.format(value);
}
if (value instanceof IEnum) {
Class<?> aClass = value.getClass();
Field desc = aClass.getDeclaredField("desc");
desc.setAccessible(true);
value = desc.get(value);
List list = new ArrayList();
list.isEmpty();
}
return value.toString();
}
}
最后
以上就是甜美芝麻为你收集整理的poi实现单元格行合并的全部内容,希望文章能够帮你解决poi实现单元格行合并所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复