3.复杂写入
3.1 复杂写入
POI复杂写出主要是同复杂读取一样,在实际开发中,从数据库中读取字符、数字、日期各种类型数据,并通过相应的计算公式写出到Excel中。
这次写出的Excel,不重新创建,而采用Excel模板(图12)形式,将数据从数据库(图13)中读出,并通过公式方式计算每个学生的总成绩、平均分,最后写入模板。
图12
图13
代码片段:
- public static HSSFWorkbook write(InputStream inputStream) throws IOException, ClassNotFoundException{
- Class clazz = Class.forName(Student.class.getName());
- Field[] fields = clazz.getDeclaredFields();
- //初始一个workbook
- HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
- List<Student> list = Conn.getData();
- //创建一个sheet
- HSSFSheet sheet = workbook.getSheetAt(0);
- //创建多行,从列名下一行开始创建
- for(int rowIndex = 1; rowIndex <= list.size(); rowIndex++){
- HSSFRow row = sheet.getRow(rowIndex);
- if(row == null){
- row = sheet.createRow(rowIndex);
- }
- Student student = list.get(rowIndex-1);
- //创建多列(不包括ID列)
- for(int cellnum = 0; cellnum < fields.length-1; cellnum++){
- HSSFCell cell = row.getCell(cellnum);
- if(cell == null){
- cell = row.createCell(cellnum);
- }
- switch (cellnum) {
- case 0:
- cell.setCellValue(new HSSFRichTextString(student.getName()));
- break;
- case 1:
- cell.setCellValue(new HSSFRichTextString(student.getNo()));
- break;
- case 2:
- cell.setCellValue(new HSSFRichTextString(student.getNativePlace()));
- break;
- case 3:
- cell.setCellValue(new HSSFRichTextString(student.getEdu()));
- break;
- case 4:
- cell.setCellValue(student.getYear());
- break;
- case 5:
- cell.setCellValue(student.getMath());
- break;
- case 6:
- cell.setCellValue(student.getChinese());
- break;
- case 7:
- cell.setCellValue(student.getEnglish());
- break;
- case 8:
- cell.setCellValue(student.getScience());
- break;
- case 9:
- cell.setCellFormula("F"+(rowIndex+1)+"+G"+(rowIndex+1)+"+H"+(rowIndex+1)+"+I"+(rowIndex+1));//写入总成绩公式
- break;
- case 10:
- cell.setCellFormula("AVERAGE(F"+(rowIndex+1)+":I"+(rowIndex+1)+")"); //写入平均成绩公式
- break;
- case 11:
- cell.setCellValue(student.isCity());
- break;
- case 12:
- cell.setCellValue(new HSSFRichTextString(formatDate(student.getSchoolDate())));
- break;
- case 13:
- cell.setCellValue(new HSSFRichTextString(formatDate(student.getBirth())));
- break;
- }
- }
- }
- return workbook;
- }
- public static String formatDate(Date date){
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- return dateFormat.format(date);
- }
- Main方法修改部分:
- public static void main(String[] args) {
- OutputStream outputStream = null;
- try {
- //读取模板
- InputStream inputStream = new FileInputStream(new File("E:\\helloPOI.xls"));
- HSSFWorkbook workbook = write(inputStream);
- outputStream = new FileOutputStream(new File("E:\\helloPOI.xls"));
- workbook.write(outputStream);
- 略.........
依赖类修改部分:
- public static List<Student> getData(){
- List<Student> list = new ArrayList<Student>();
- Connection conn = getConn();
- String sql = "SELECT * FROM tpoi_vintage t";
- try {
- conn.setAutoCommit(false);
- PreparedStatement ps = conn.prepareStatement(sql);
- ResultSet rs = ps.executeQuery();
- while(rs.next()){
- Integer id = rs.getInt("id");
- String name = rs.getString("name");
- String no = rs.getString("no");
- String nativePlace = rs.getString("native");
- String edu = rs.getString("edu");
- Integer year = rs.getInt("YEAR");
- Integer math = rs.getInt("MATH");
- Integer chinese = rs.getInt("CHINESE");
- Integer english = rs.getInt("ENGLISH");
- Integer science = rs.getInt("SCIENCE");
- Integer isCity = rs.getInt("ISCITY");
- Date schoolDate = rs.getDate("SCHOOLDATE");
- Date birth = rs.getDate("BIRTH");
- Student student = new Student();
- student.setId(id);
- student.setName(name);
- student.setNo(no);
- student.setNativePlace(nativePlace);
- student.setEdu(edu);
- student.setYear(year);
- student.setMath(math);
- student.setChinese(chinese);
- student.setEnglish(english);
- student.setScience(science);
- if(isCity == 0){
- student.setCity(false);
- }else if(isCity == 1){
- student.setCity(true);
- }
- student.setSchoolDate(schoolDate);
- student.setBirth(birth);
- list.add(student);
- }
- conn.commit();
- public class Student {
- private Integer id;
- private String name;
- private String no;
- private String nativePlace;
- private String edu;
- private Integer year;
- private Integer math;
- private Integer chinese;
- private Integer english;
- private Integer science;
- private Integer scores;
- private Integer ave;
- private boolean isCity;
- private Date schoolDate;
- private Date birth;
- 略.. .
输出结果图14:
图14
3.2 多层公式
多层公式引用是实际开发中常见的情况,例如有A列、B列、C列数据,A列为初始就有数值,B列为公式依赖于A列,C列为公式依赖于A列和B列,这样的情况,以及各种统计计算。在此多层公式引用情况下,有可能打开Excel后,公式列获取焦点后再手动移开,公式才生效,所以需要对sheet设置sheet.setForceFormulaRecalculation(true)。
现在模拟下多层公式引用,增加一列平均分,通过“总成绩/4”计算,增加一行总计信息。
代码片段:
- public static HSSFWorkbook write(InputStream inputStream) throws IOException, ClassNotFoundException{
- Class clazz = Class.forName(Student.class.getName());
- Field[] fields = clazz.getDeclaredFields();
- //初始一个workbook
- HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
- List<Student> list = Conn.getData();
- //创建一个sheet
- HSSFSheet sheet = workbook.getSheetAt(0);
- sheet.setForceFormulaRecalculation(true);
- int currentRowIndex = 0;
- //创建多行,从列名下一行开始创建
- for(int rowIndex = 1; rowIndex <= list.size(); rowIndex++){
- currentRowIndex = rowIndex;
- HSSFRow row = sheet.getRow(rowIndex);
- if(row == null){
- row = sheet.createRow(rowIndex);
- }
- Student student = list.get(rowIndex-1);
- //创建多列(不包括ID列)
- for(int cellnum = 0; cellnum < fields.length; cellnum++){
- HSSFCell cell = row.getCell(cellnum);
- if(cell == null){
- cell = row.createCell(cellnum);
- }
- switch (cellnum) {
- case 0:
- cell.setCellValue(new HSSFRichTextString(student.getName()));
- break;
- case 1:
- cell.setCellValue(new HSSFRichTextString(student.getNo()));
- break;
- case 2:
- cell.setCellValue(new HSSFRichTextString(student.getNativePlace()));
- break;
- case 3:
- cell.setCellValue(new HSSFRichTextString(student.getEdu()));
- break;
- case 4:
- cell.setCellValue(student.getYear());
- break;
- case 5:
- cell.setCellValue(student.getMath());
- break;
- case 6:
- cell.setCellValue(student.getChinese());
- break;
- case 7:
- cell.setCellValue(student.getEnglish());
- break;
- case 8:
- cell.setCellValue(student.getScience());
- break;
- case 9:
- cell.setCellFormula("F"+(rowIndex+1)+"+G"+(rowIndex+1)+"+H"+(rowIndex+1)+"+I"+(rowIndex+1));
- break;
- case 10:
- cell.setCellFormula("AVERAGE(F"+(rowIndex+1)+":I"+(rowIndex+1)+")");
- break;
- case 11:
- cell.setCellFormula("J"+(rowIndex+1)+"/4");
- break;
- case 12:
- cell.setCellValue(student.isCity());
- break;
- case 13:
- cell.setCellValue(new HSSFRichTextString(formatDate(student.getSchoolDate())));
- break;
- case 14:
- cell.setCellValue(new HSSFRichTextString(formatDate(student.getBirth())));
- break;
- }
- }
- }
- currentRowIndex++;
- HSSFRow row = sheet.createRow(currentRowIndex);
- HSSFCell cell0 = row.createCell(0);
- HSSFCell cell5 = row.createCell(5);
- HSSFCell cell6 = row.createCell(6);
- HSSFCell cell7 = row.createCell(7);
- HSSFCell cell8 = row.createCell(8);
- HSSFCell cell9 = row.createCell(9);
- HSSFCell cell10 = row.createCell(10);
- HSSFCell cell11 = row.createCell(11);
- cell0.setCellValue(new HSSFRichTextString("总计"));
- cell5.setCellFormula("SUM(F1:F"+currentRowIndex+")");
- cell6.setCellFormula("SUM(G1:G"+currentRowIndex+")");
- cell7.setCellFormula("SUM(H1:H"+currentRowIndex+")");
- cell8.setCellFormula("SUM(I1:I"+currentRowIndex+")");
- cell9.setCellFormula("SUM(J1:J"+currentRowIndex+")");
- cell10.setCellFormula("AVERAGE(K1:K"+currentRowIndex+")");
- cell11.setCellFormula("AVERAGE(L1:L"+currentRowIndex+")");
- return workbook;
- }
输出结果:
图15