POI 导出Excel文件

需要导出的格式图片:


工具类:

package com.tahoe.web.controller.land;

import com.tahoe.api.land.model.view.LandinformationView;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;

import javax.swing.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * POI导出Excel文件
 *
 * @param <T>
 * @author W
 * @Date 2018-06-06
 */
public class ExportExcelUtils<T> {

    public XSSFWorkbook exportExcel(String[] headers, Collection<T> dataset, String[] columns) {
        XSSFWorkbook workbook = exportExcel(headers, dataset, columns, "yyyy-MM-dd");
        return workbook;
    }

    /**
     * 导出文件
     *
     * @param headers 表格属性列名数组
     * @param dataset 需要显示的数据集合
     * @param pattern 如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
     */
    public XSSFWorkbook exportExcel(String[] headers,
                                    Collection<T> dataset, String[] columns, String pattern) {
        // 声明一个工作薄
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 生成一个表格
        XSSFSheet sheet = workbook.createSheet();
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 15);
        // 生成一个样式
        XSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//居中
        // 生成一个字体
        XSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 12);
        // 把字体应用到当前的样式
        style.setFont(font);

        // 生成一个字体
        XSSFFont font1 = workbook.createFont();
        font1.setFontHeightInPoints((short) 20);
        font1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // 产生表格标题行
        XSSFRow row = sheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            XSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            XSSFRichTextString text = new XSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }

        // 遍历集合数据,产生数据行
        Iterator<T> it = dataset.iterator();
        int index = 0;
        while (it.hasNext()) {
            index++;
            row = sheet.createRow(index);
            T t = (T) it.next();

            // 添加序号
            XSSFCell cell0 = row.createCell(0);
            cell0.setCellStyle(style);
            cell0.setCellValue(row.getRowNum());

            // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
            for (int i = 0; i < columns.length; i++) {
                // 循环添加单元格数据
                XSSFCell cell = row.createCell(i + 1);
                cell.setCellStyle(style);
                String fieldName = columns[i];
                String getMethodName = "get"
                        + fieldName.substring(0, 1).toUpperCase()
                        + fieldName.substring(1);
                try {
                    Class tCls = t.getClass();
                    Method getMethod = tCls.getMethod(getMethodName,
                            new Class[]
                                    {});
                    Object value = getMethod.invoke(t, new Object[]
                            {});
                    // 判断值的类型后进行强制类型转换
                    String textValue = null;
                    if (value instanceof Date) {
                        Date date = (Date) value;
                        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                        textValue = sdf.format(date);
                    } else {
                        // 其它数据类型都当作字符串简单处理
                        if (value == null) {
                            textValue = "";
                        } else {
                            textValue = value.toString();
                        }
                    }
                    // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
                    if (textValue != null) {
                        XSSFRichTextString richString = new XSSFRichTextString(textValue);
                        XSSFFont font3 = workbook.createFont();
                        richString.applyFont(font3);
                        cell.setCellValue(richString);
                    }
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } finally {
                    // 清理资源
                }
            }
        }

        return workbook;
    }


    /**
     * 导出产品定位信息 私人定制
     *
     * @param dataset 需要显示的数据集合
     * @param pattern 如果有时间数据,设定输出格式。默认为"yyy-MM-dd"
     */
    public XSSFWorkbook exportExcelByProductPosition(Collection<T> dataset, String[] columns, String pattern) {
        // 声明一个工作薄
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 生成一个表格
        XSSFSheet sheet = workbook.createSheet();

        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 15);
        // 生成一个样式
        XSSFCellStyle style = workbook.createCellStyle();
        // 设置边框
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        // 设置居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平
        // 自动适应宽度
        sheet.autoSizeColumn(1, true);

        // 生成一个字体
        XSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 12);
        // 把字体应用到当前的样式
        style.setFont(font);

        // 生成一个字体
        XSSFFont font1 = workbook.createFont();
        font1.setFontHeightInPoints((short) 20);
        font1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        XSSFRow row = sheet.createRow(0);
        XSSFRow row1 = sheet.createRow(1);

        // 合并单元格 //参数1:行号 参数2:起始列号 参数3:行号 参数4:终止列号
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 1, 1));
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 3));
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 4, 5));
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 6, 7));
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 8, 8));
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 9, 9));
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 10, 10));

        // 产生表格标题行

        row.createCell(0).setCellStyle(style);
        row.getCell(0).setCellValue("类别");

        row.createCell(1).setCellStyle(style);
        row.getCell(1).setCellValue("总面积(");

        row.createCell(2).setCellStyle(style);
        row.createCell(3).setCellStyle(style);
        row.getCell(2).setCellValue("户型面积(");//2-3

        row.createCell(4).setCellStyle(style);
        row.createCell(5).setCellStyle(style);
        row.getCell(4).setCellValue("销售均价(万元/m²");//4-5

        row.createCell(6).setCellStyle(style);
        row.createCell(7).setCellStyle(style);
        row.getCell(6).setCellValue("套总价段(万元)");//6-7

        row.createCell(8).setCellStyle(style);
        row.getCell(8).setCellValue("保本售价(万元/m²");

        row.createCell(9).setCellStyle(style);
        row.getCell(9).setCellValue("总货值(万元)");

        row.createCell(10).setCellStyle(style);
        row.getCell(10).setCellValue("备注");

        // 第二行
        row1.createCell(0).setCellStyle(style);
        row1.createCell(7).setCellStyle(style);
        row1.createCell(8).setCellStyle(style);
        row1.createCell(9).setCellStyle(style);
        row1.createCell(10).setCellStyle(style);
        row1.createCell(2).setCellStyle(style);
        row1.getCell(2).setCellValue("产权面积");

        row1.createCell(3).setCellStyle(style);
        row1.getCell(3).setCellValue("使用面积");

        row1.createCell(4).setCellStyle(style);
        row1.getCell(4).setCellValue("产权单价");

        row1.createCell(5).setCellStyle(style);
        row1.getCell(5).setCellValue("使用面积单价");


        // 遍历集合数据,产生数据行
        Iterator<T> it = dataset.iterator();
        int index = 1;
        while (it.hasNext()) {
            index++;
            row = sheet.createRow(index);
            T t = (T) it.next();

            // 添加序号
            XSSFCell cell0 = row.createCell(0);
            cell0.setCellStyle(style);
            cell0.setCellValue(row.getRowNum() - 1);

            // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
            for (int i = 0; i < columns.length; i++) {
                // 循环添加单元格数据
                XSSFCell cell = row.createCell(i);
                cell.setCellStyle(style);
                String fieldName = columns[i];
                String getMethodName = "get"
                        + fieldName.substring(0, 1).toUpperCase()
                        + fieldName.substring(1);
                try {
                    Class tCls = t.getClass();
                    Method getMethod = tCls.getMethod(getMethodName,
                            new Class[]
                                    {});
                    Object value = getMethod.invoke(t, new Object[]
                            {});
                    // 判断值的类型后进行强制类型转换
                    String textValue = null;
                    if (value instanceof Date) {
                        Date date = (Date) value;
                        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                        textValue = sdf.format(date);
                    } else {
                        // 其它数据类型都当作字符串简单处理
                        if (value == null) {
                            textValue = "";
                        } else {
                            textValue = value.toString();
                        }
                    }
                    // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
                    if (textValue != null) {
                        XSSFRichTextString richString = new XSSFRichTextString(textValue);
                        XSSFFont font3 = workbook.createFont();
                        richString.applyFont(font3);
                        cell.setCellStyle(style);
                        cell.setCellValue(richString);
                    } else {
                        cell.setCellStyle(style);
                        cell.setCellValue("");
                    }
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } finally {
                    // 清理资源
                }
            }
        }

        return workbook;
    }


    public static void main(String[] args) {
        // 测试土地信息导出
        ExportExcelUtils<LandinformationView> ex = new ExportExcelUtils<LandinformationView>();
        String[] headers = {"序号", "城市", "地块名称", "项目性质", "占地面积(m²)", "容积率", "货值(万)", "土地状态",
                "负责人", "最近跟进日期"};
        String[] columns = {"regionName", "projectName", "purposeName", "areaCovered", "volumetricRate", "landVale", "stateName",
                "personCharge", "followTime"};
        List<LandinformationView> dataset = new ArrayList<LandinformationView>();
        LandinformationView view = new LandinformationView();
        view.setProjectName("土地信息1");
        view.setRegionName("北京");
        view.setPurposeName("住宅");
        view.setAreaCovered(new BigDecimal("111.99"));
        view.setLandVale(new BigDecimal("23524.88"));
        view.setStateName("已确权");
        view.setPersonCharge("张三");
        view.setFollowTime(new Date());
        dataset.add(view);
        try {
            OutputStream out = new FileOutputStream("E://aa.xlsx");
            XSSFWorkbook workbook = ex.exportExcelByProductPosition(dataset, columns, "yyyy-MM-dd");
            workbook.write(out);
            out.close();
            JOptionPane.showMessageDialog(null, "导出成功!");
            System.out.println("excel导出成功!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
    }
}

Contrller层实现:

// 生成excel 并写入到浏览器中
ExportExcelUtils<ProductPositionView> ex = new ExportExcelUtils<ProductPositionView>();
String[] columns = {"category", "totalArea", "propertyArea", "useArea", "propertyPrice", "useAreaPrice",
        "totalSection", "totalSectionMark", "costSave", "totalValue", "remarks"};
XSSFWorkbook workbook = ex.exportExcelByProductPosition(views, columns, "yyyy-MM-dd");

// 下载的文件名
String fileName = "产品定位列表" + new Date().getTime() + ".xlsx";
OutputStream output = response.getOutputStream();
response.setCharacterEncoding("UTF-8");
response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("gbk"), "iso8859-1"));

workbook.write(output);
output.close();


总结:

    正常的列表标题和数据都是动态公用的,有单独的样式是私人定制的。数据是提前准备好的,与生成Excel是分开的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个完整的 Java POI 导出 Excel 文件并下载的示例代码: ```java import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelExportUtil { public static void export(HttpServletResponse response) throws IOException { // 创建工作簿 Workbook workbook = new XSSFWorkbook(); // 创建工作表 Sheet sheet = workbook.createSheet("Sheet1"); // 添加表头行 Row headerRow = sheet.createRow(0); Cell headerCell1 = headerRow.createCell(0); headerCell1.setCellValue("Name"); Cell headerCell2 = headerRow.createCell(1); headerCell2.setCellValue("Age"); // 添加数据行 List<Person> personList = getPersonList(); for (int i = 0; i < personList.size(); i++) { Person person = personList.get(i); Row row = sheet.createRow(i + 1); Cell cell1 = row.createCell(0); cell1.setCellValue(person.getName()); Cell cell2 = row.createCell(1); cell2.setCellValue(person.getAge()); } // 设置响应头,告诉浏览器下载文件 response.setHeader("Content-Disposition", "attachment;filename=example.xlsx"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 将工作簿写入响应输出流 workbook.write(response.getOutputStream()); // 关闭工作簿 workbook.close(); } private static List<Person> getPersonList() { List<Person> personList = new ArrayList<>(); personList.add(new Person("Alice", 20)); personList.add(new Person("Bob", 25)); personList.add(new Person("Charlie", 30)); return personList; } private static class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } } ``` 这段代码定义了一个名为 `ExcelExportUtil` 的类,其中包含了一个名为 `export` 的静态方法,用于导出 Excel 文件并下载。在 `export` 方法中,首先创建了一个工作簿对象 `workbook`,然后创建了一个工作表对象 `sheet`,并向其中添加了表头行和数据行。最后将工作簿写入响应输出流,并设置响应头,告诉浏览器下载文件。 在 `getPersonList` 方法中,定义了一个名为 `Person` 的内部类,用于存储人员信息。在示例代码中,生成了一个包含三个人员信息的列表。 如果需要调用上述代码,可以在 Servlet 或者 Spring MVC 的控制器中使用以下代码: ```java @RequestMapping("/download") public void download(HttpServletResponse response) throws IOException { ExcelExportUtil.export(response); } ``` 其中 `"/download"` 是一个映射到下载方法的 URL。这段代码会调用 `ExcelExportUtil` 类的静态方法 `export`,并将响应对象 `response` 传递给它。需要注意的是,需要将 `HttpServletResponse` 对象作为参数传递给 `export` 方法,以便将 Excel 文件写入响应输出流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值