ssm框架中导出excel文件

一、先在pom.xml中引入poi依赖

<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>3.15</version>
</dependency>

 关于办公文档插件使用的基本思想:把办公文档的所有元素封装成普通的Java类,程序员通过操作这些类达到操作办公文档的目的。

        文件——HSSFWorkbook

        页——HSSFSheet

        行——HSSFRow

        列——HSSFCell

        样式——HSSFCellStyle

二、JSP页面

给导出按钮设置id="exportActivityAllBtn",添加单击事件发送请求

$("#exportActivityAllBtn").click(function () {

    window.location.href="exportAllActivitys.do" ;

 });

 三、Controller层,使用返回的activityList导出到excel

@RequestMapping("/exportAllActivitys.do")
    public void exportAllActivitys(HttpServletResponse response) throws Exception{
        //调用service返回activityList
        List<Activity> activityList = activityService.queryAllActivitys();
        //用apache的poi创建excel文件,并把activityList写入excel文件中
        //创建HSSFWorkbook对象,对应一个excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        //使用wb创建HSSFSheet对象,对应wb文件中的一页
        HSSFSheet sheet = wb.createSheet("市场活动列表");//设置页名
        //使用sheet创建HSSFRow对象,对应sheet中的一行
        HSSFRow row = sheet.createRow(0);//索引为0就是第一行
        //使用row创建HSSFCell对象,对应row中的列
        HSSFCell cell = row.createCell(0);//索引为0就是第一列
        //往列里设置值
        cell.setCellValue("ID");
        cell = row.createCell(1);
        cell.setCellValue("所有者");
        cell = row.createCell(2);
        cell.setCellValue("活动名称");
        cell = row.createCell(3);
        cell.setCellValue("开始日期");
        cell = row.createCell(4);
        cell.setCellValue("结束日期");
        cell = row.createCell(5);
        cell.setCellValue("成本");
        cell = row.createCell(6);
        cell.setCellValue("描述");
        cell = row.createCell(7);
        cell.setCellValue("创建时间");
        cell = row.createCell(8);
        cell.setCellValue("创建者");
        cell = row.createCell(9);
        cell.setCellValue("修改时间");
        cell = row.createCell(10);
        cell.setCellValue("修改者");

        //遍历ActivityList,创建Row
        //先判断list有没有数据
        if(activityList!=null&&activityList.size()>0){
            Activity activity=null;//activity拿到外面定义就不用每次循环都创建,效率更高
            for(int i=0;i<activityList.size();i++){
                activity = activityList.get(i);
                //每遍历出一个activity,生成一行
                row=sheet.createRow(i+1);
                cell = row.createCell(0);
                cell.setCellValue(activity.getId());
                cell = row.createCell(1);
                cell.setCellValue(activity.getOwner());
                cell = row.createCell(2);
                cell.setCellValue(activity.getName());
                cell = row.createCell(3);
                cell.setCellValue(activity.getStartDate());
                cell = row.createCell(4);
                cell.setCellValue(activity.getEndDate());
                cell = row.createCell(5);
                cell.setCellValue(activity.getCost());
                cell = row.createCell(6);
                cell.setCellValue(activity.getDescription());
                cell = row.createCell(7);
                cell.setCellValue(activity.getCreateTime());
                cell = row.createCell(8);
                cell.setCellValue(activity.getCreateBy());
                cell = row.createCell(9);
                cell.setCellValue(activity.getEditTime());
                cell = row.createCell(10);
                cell.setCellValue(activity.getEditBy());
            }
        }


        //改进后!!!!!!!!!!!!!!!!!!!!!

        //设置响应类型 application/octet-stream表示excel文件
        response.setContentType("application/octet-stream;charset=UTF-8");
        //设置响应头  Content-Disposition打开方式 attachment以附件的形式
        response.addHeader("Content-Disposition","attachment;filename=AllactivityList.xls");
        OutputStream out = response.getOutputStream();
        wb.write(out);
        wb.close();
        out.flush();//out由response生成的,tomcat会自己关闭,不能自己关闭,不flush可能会数据丢失
    }

记得配置扫描Controller

四、Service和实现类

public interface ActivityService {

    List<Activity> queryAllActivitys();

}
@Service("activityService")
public class ActivityServiceImpl implements ActivityService{
    @Autowired
    ActivityMapper activityMapper;

    @Override
    public List<Activity> queryAllActivitys() {
        return activityMapper.selectAllActivitys();
    }


}
记得配置扫描Service

五、Dao和mapper

public interface ActivityMapper {

    //查询所有市场活动
    List<Activity> selectAllActivitys();

}
<select id="selectAllActivitys" resultMap="BaseResultMap">
    select a.id , u1.name as owner, a.name, a.start_date, a.end_date, a.cost, a.description, a.create_time,
            u2.name as create_by, a.edit_time, u3.name as edit_by
    from tbl_activity a
    join tbl_user u1 on a.owner = u1.id
    join tbl_user u2 on a.create_by = u2.id
    left join tbl_user u3 on a.edit_by =u3.id
    order by a.create_time desc
</select>
记得配置mapper注解扫描器

六、改进

先写到磁盘再读取磁盘效率太低了,正好workbook对象里有个方法wb.write(out) ,把workbook对象里的数据输出到outputStream对象out里,直接让它输出到浏览器。下面是未改前,上面已经改了。


        OutputStream os = new FileOutputStream("E:\\serverDir\\activityList.xls");
        wb.write(os);//wb.write(os)表示你要吧它生成到哪个文件。从内存写到磁盘。内存访问磁盘效率是很低的,要建立链接,占内存,占cpu,不亚于访问一次数据库
        os.close();
        wb.close();
        //把生成的excel文件下载到客户端
        //设置响应类型 application/octet-stream表示excel文件
        response.setContentType("application/octet-stream;charset=UTF-8");
        //设置响应头  Content-Disposition打开方式 attachment以附件的形式
        response.addHeader("Content-Disposition","attachment;filename=AllactivityList.xls");
        OutputStream out = response.getOutputStream();
        InputStream is = new FileInputStream("E:\\serverDir\\activityList.xls");//从磁盘读到内存,要建立链接,占内存,占cpu,不亚于访问一次数据库
        //缓存区,以一个字节数组为单位读更快
        byte[] buff = new byte[256];
        int len=0; //实际读取个数,等于-1时说明读完了
        while((len=is.read(buff))!=-1){
            out.write(buff,0,len);
        }
        is.close();
        out.flush();//out由response生成的,tomcat会自己关闭,不能自己关闭,不flush可能会数据丢失,因为可能还在缓冲区里
    

七、总结

导出功能不能使用异步请求,这样下载框弹不出来,只能使用同步请求(三种:地址栏、超链接、表单)

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值