在研究jxls时 想生成的模板 和传入的javabean 怎么样才可以做到 动态合并 相邻行的同一信息的单元格
比如
王五 1 王五 1
王五 2 合并成: 2
王刘 3 王刘 3
看了很多博客 再结合自己的研究 和文档 发现 只能通过 先生成 没有合并过的输出流 转成 工作薄对象 再进行加工 从而 输出 思路为:先得到要传入到模板上的list 设置想要 合并的字段名 比如name (当然 这个list得要是后台按groupby 传来有顺序的。。毕竟 我的程序还是比较年幼) 找出相同名字的 起始位置 用poi进行单元格合并
首先 写了两个实体 1.为了模拟测试 的student类
package workdemo.entity;
public class Student {
private String name;
private String subject;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Student(String name, String subject, int score) {
super();
this.name = name;
this.subject = subject;
this.score = score;
}
}
2.为了方便记录起始位置 我写了一个类
package workdemo.entity;
public class Merge {
private int fromRow;
private int toRow;
private int fromIndex;
private int toIndex;
public int getFromRow() {
return fromRow;
}
public void setFromRow(int fromRow) {
this.fromRow = fromRow;
}
public int getToRow() {
return toRow;
}
@Override
public String toString() {
return "Merge [fromRow=" + fromRow + ", toRow=" + toRow + ", fromIndex=" + fromIndex + ", toIndex=" + toIndex
+ "]";
}
public void setToRow(int toRow) {
this.toRow = toRow;
}
public int getFromIndex() {
return fromIndex;
}
public void setFromIndex(int fromIndex) {
this.fromIndex = fromIndex;
}
public int getToIndex() {
return toIndex;
}
public void setToIndex(int toIndex) {
this.toIndex = toIndex;
}
}
3.主函数 基于反射写了个方法 降低耦合度
package com.icom.util.base.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import com.icom.util.base.test.entity.Merge;
import com.icom.util.base.test.entity.Student;
import net.sf.jxls.exception.ParsePropertyException;
import net.sf.jxls.transformer.XLSTransformer;
public class Main {
public static List gen() {
// 模拟生成 一个学生list 经过排列 特意有几个是同一个学生考的
List list = new ArrayList();
for (int i = 50; i < 55; i++) {
list.add(new Student("吴承接", "数学", i));
}
list.add(new Student("多大的", "物理", 55));
list.add(new Student("多大的", "化学", 99));
list.add(new Student("多大的", "信息", 56));
list.add(new Student("呵呵", "物理", 55));
list.add(new Student("蛋蛋", "物理", 55));
list.add(new Student("蛋蛋", "物无", 55));
list.add(new Student("鸡儿", "物理", 55));
return list;
}
// 先用String
public static Object useMethod(T t, String sx) throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
// 一般传入get方法
return (Object) t.getClass().getMethod(sx, null).invoke(t, null);
}
public static List getMerge(List list, String sx) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
// 可以传入 想合并的属性值 传入一个字符串 用反射找到相应的get方法 指定调用此方法。。这里先写死
List ml = new ArrayList();
for (int i = 0; i < list.size() - 1; i++) {
if (useMethod(list.get(i), sx) == useMethod(list.get(i + 1), sx)) {
Object property = useMethod(list.get(i), sx);
// System.out.println(property);
// System.out.println("第" + (i + 1) + "个和第" + i + "个一样");
Merge merge = new Merge();
int fromRow = i, toRow = i + 1;
if (i + 2 < list.size()) {
for (int j = i + 2; j < list.size(); j++) {
if (useMethod(list.get(j), sx) == property) {
toRow++;
} else {
i = j - 1;
break;
}
}
}
merge.setFromRow(fromRow);
merge.setToRow(toRow);
ml.add(merge);
}
}
return ml;
}
public static void main(String[] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, FileNotFoundException, ParsePropertyException, InvalidFormatException {
String templateFile = "d://test//mergedemo.xls";
Map beans = new HashMap();
InputStream is = new FileInputStream(templateFile);
List data = gen();
beans.put("data", data);
XLSTransformer transformer = new XLSTransformer();
HSSFWorkbook workBook = (HSSFWorkbook) transformer.transformXLS(is, beans); // 传入模板的输入流和map
// 开始进行合并单元格
HSSFSheet sheet = workBook.getSheetAt(0);// 1 1
List ml = getMerge(gen(), "getName");
for (Merge m : ml) {
// 因为知道是第一列 的合并 所以写死 行+1是因为 第一行是列名
sheet.addMergedRegion(new CellRangeAddress(m.getFromRow() + 1, m.getToRow() + 1, 0, 0));
}
try {
OutputStream os = new FileOutputStream("d://test//mergeResult.xls");
workBook.write(os);
is.close();
os.flush();
os.close();
} catch (IOException ie) {
ie.printStackTrace();
} catch (ParsePropertyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4.excle 模板
5.输出结果:
最后就可以得到 装有Merge对象的list 循环list 就可以调用 poi里的 addMergedRegion( CellRangeAddress cellRangeAddress ) 进行合并
还是蛮有收获的。。。。。。复习了反射~