要实现的功能很简单,就是把java对象转换为Execl文档并保存到本地。
Excel文件分析
主要由三个组件组成:sheet ,row, column。如下图:
想要向上图excel表中插入数据,要以下几个步骤:
- 找到对应的sheet;
- 设置每一列的列名;
- 为每一行插入数据。
编程思路
定义一个类,参数用来描述需要插入文档的列名;
实例化类,描述需要插入的数据;
-
根据列名和属性的对应关系,遍历对象对每一行数据赋值。
技术实现
1.使用工具包jxl。添加maven依赖:
<!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
2.定义注解类,列名:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XlsName {
String value() default "";
}
3.定义Student对象.
public class Student {
@XlsName(value = "编号")
private int id;
@XlsName(value = "姓名")
private String name;
@XlsName(value = "年龄")
private String age;
public int getId() {
return id;
}
public Student setId(int id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public String getAge() {
return age;
}
public Student setAge(String age) {
this.age = age;
return this;
}
}
3.实现功能:
public class XlsGenTest {
// 模拟数据库生成数据
private static List<Student> list = new ArrayList<>();
static {
list.add(new Student().setId(1).setAge("11").setName("喜洋洋"));
list.add(new Student().setId(2).setAge("22").setName("美羊羊"));
list.add(new Student().setId(3).setAge("33").setName("懒洋洋"));
}
public static void main(String[] args) throws IOException, BiffException, WriteException, InterruptedException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 找到一个文件
File file = new File("F:\\fletest\\merchant.xls");
WritableWorkbook writableWorkbook = Workbook.createWorkbook(file);
// 创建一个sheet表格
WritableSheet sheet = writableWorkbook.createSheet("sheet1", 0);
// 获取需要转换为excel的类
Class<?> clazz = Class.forName("com.zxerjones.Filettt.Student");
List<Field> titleField = Arrays.asList(clazz.getDeclaredFields());
if (titleField.size() == 0) {
return;
}
// 获取column和method的映射关系
Map<String , String> titlesMap = titleField.parallelStream()
.filter(e -> e.getDeclaredAnnotation(XlsName.class) != null)
.collect(Collectors.toMap(k -> {
XlsName xlsName = k.getDeclaredAnnotation(XlsName.class);
return xlsName.value();
}, v -> {
// 绑定类中的参数和列名
String fieldName = v.getName();
String method = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
return method;
}));
// 没有找到
if (titlesMap.isEmpty()) {
return;
}
// 保证column的顺序,使用list存储column
List<String> titlesList = titleField.parallelStream()
.filter(e -> e.getDeclaredAnnotation(XlsName.class) != null)
.map(e -> e.getAnnotation(XlsName.class).value())
.collect(Collectors.toList());
Label label = null;
// 设置第一行,列名
for (int i = 0; i < titlesList.size(); i++) {
label = new Label(i, 0, String.valueOf(titlesList.get(i)));
sheet.addCell(label);
sheet.getCell(0, 0);
}
// 循环录入数据,根据@xlsName.value()的值在map中寻找method
for (int i = 0; i < list.size(); i++) {
Student temS = list.get(i);
for (int j = 0; j < titlesList.size(); j++) {
String labelValue = String.valueOf(temS.getClass().getMethod(titlesMap.get(titlesList.get(j)))
.invoke(temS)) ;
label = new Label(j, i + 1, labelValue);
sheet.addCell(label);
}
}
// 开始写入文档,切记这一行代码一定要写
writableWorkbook.write();
// 关闭流
writableWorkbook.close();
}
}
4.效果演示:
参考博客:
jxl的使用总结(java操作excel)。