基于POI导出Excel数据

POI进阶:向Excel中插入图片http://cmsblogs.com/?p=557

 基于POI导出Excel数据

  在项目中会有许多报表业务,需要导出数据。在这里我们采用基于POI的方式解析。POI有俩种解析方式HSSF(xls格式)和XSSF(xlsx)。

POI结构与常用类

(1)POI介绍

     Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。

(2)POI结构说明

 

包名称说明

HSSF提供读写Microsoft Excel XLS格式档案的功能。

XSSF提供读写Microsoft Excel OOXML XLSX格式档案的功能。

HWPF提供读写Microsoft Word DOC格式档案的功能。

HSLF提供读写Microsoft PowerPoint格式档案的功能。

HDGF提供读Microsoft Visio格式档案的功能。

HPBF提供读Microsoft Publisher格式档案的功能。

HSMF提供读Microsoft Outlook格式档案的功能。

(3)POI常用类说明

类名                     说明

HSSFWorkbook           Excel的文档对象

HSSFSheet                 Excel的表单

HSSFRow                   Excel的行

HSSFCell                    Excel的格子单元

HSSFFont                   Excel字体

HSSFDataFormat        格子单元的日期格式

HSSFHeader             Excel文档Sheet的页眉

HSSFFooter             Excel文档Sheet的页脚

HSSFCellStyle          格子单元样式

HSSFDateUtil           日期

HSSFPrintSetup        打印

 

HSSFErrorConstants   错误信息表

以BOS物流的运单管理界面为例:

前端代码

 导出运单信息,生成报表:

  1.添加导出按钮

  2.添加导出事件

 

后台代码实现

 POI生成Excel步骤写Excel过程一样,新建Excel文档----新建Sheet---新建Row---新建Cell单元格---写单元格数据。

Maven导入jar包信息请参加一键上传里面的配置

Action层代码实现

@Controller
@Scope("prototype")
@ParentPackage("json-default")
@Namespace("/")
public class ExportXlsAction extends BaseAction<WayBill>{

    @Autowired
    private WayBillService  wayBillService;
    
    @Action("report_exportXls")
    public String exportXls() throws Exception{
        //查询出,满足当前条件的结果数据
        List<WayBill> waybills = wayBillService.findwayBills(model);
        
        // 生成Excel文件(xls格式)
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        HSSFSheet sheet = hssfWorkbook.createSheet("运单数据");//创建一个sheet对象
        
        // 表头(表格的第一行)
        HSSFRow headRow = sheet.createRow(0);//创建第一行对象
        headRow.createCell(0).setCellValue("运单号");//创建了第一个格子它的属性是运单号
        headRow.createCell(1).setCellValue("寄件人");//创建了第二个格子...
        headRow.createCell(2).setCellValue("寄件人电话");
        headRow.createCell(3).setCellValue("寄件人地址");
        headRow.createCell(4).setCellValue("收件人");
        headRow.createCell(5).setCellValue("收件人电话");
        headRow.createCell(6).setCellValue("收件人地址");
        
        // 表格数据(遍历拿到的数据,一个对象信息对应一行记录)
        for (WayBill wayBill : waybills) {//拿到最后一行的行号
            HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);
            dataRow.createCell(0).setCellValue(wayBill.getWayBillNum());
            dataRow.createCell(1).setCellValue(wayBill.getSendName());
            dataRow.createCell(2).setCellValue(wayBill.getSendMobile());
            dataRow.createCell(3).setCellValue(wayBill.getSendAddress());
            dataRow.createCell(4).setCellValue(wayBill.getRecName());
            dataRow.createCell(5).setCellValue(wayBill.getRecMobile());
            dataRow.createCell(6).setCellValue(wayBill.getRecAddress());
        }

        // 下载导出
        // 设置头信息(设置文件类型 xls)
        ServletActionContext.getResponse().setContentType(
                "application/vnd.ms-excel");
        String filename = "运单数据.xls";
        String agent = ServletActionContext.getRequest()
                .getHeader("user-agent");//得到浏览器类型(火狐,360,IE)
        filename = FileUtils .encodeDownloadFilename(filename, agent);
        ServletActionContext.getResponse().setHeader("Content-Disposition",
                "attachment;filename=" + filename);
               //filename:设置生产Excel的文件名  FileUtils:是针对浏览器类型的中文编码类
        ServletOutputStream outputStream = ServletActionContext.getResponse()
                .getOutputStream();//得到一个响应流对象
        hssfWorkbook.write(outputStream);

        // 关闭
        hssfWorkbook.close();

        return NONE;        
    }
}
Action层代码
package cn.itcast.bos.utils;

import java.io.IOException;
import java.net.URLEncoder;

import sun.misc.BASE64Encoder;

public class FileUtils {
        /**
         * 下载文件时,针对不同浏览器,进行附件名的编码
         * 
         * @param filename
         *            下载文件名
         * @param agent
         *            客户端浏览器
         * @return 编码后的下载附件名
         * @throws IOException
         */
        public static String encodeDownloadFilename(String filename, String agent)
                throws IOException {
            if (agent.contains("Firefox")) { // 火狐浏览器
                filename = "=?UTF-8?B?"
                        + new BASE64Encoder().encode(filename.getBytes("utf-8"))
                        + "?=";
                filename = filename.replaceAll("\r\n", "");
            } else { // IE及其他浏览器
                filename = URLEncoder.encode(filename, "utf-8");
                filename = filename.replace("+"," ");
            }
            return filename;
        }
}
FileUtils类
public List<WayBill> findwayBills(WayBill wayBill) {
        if (StringUtils.isBlank(wayBill.getWayBillNum())
                && StringUtils.isBlank(wayBill.getSendAddress())
                && StringUtils.isBlank(wayBill.getRecAddress())
                && StringUtils.isBlank(wayBill.getSendProNum())
                && (wayBill.getSignStatus() == null || wayBill.getSignStatus() == 0)) {
            // 无条件查询 、查询数据库
            return wayBillRepository.findAll();
        } else {
            // 查询条件
            // must 条件必须成立 and
            // must not 条件必须不成立 not
            // should 条件可以成立 or
            BoolQueryBuilder query = new BoolQueryBuilder(); // 布尔查询 ,多条件组合查询
            // 向组合查询对象添加条件
            if (StringUtils.isNoneBlank(wayBill.getWayBillNum())) {
                // 运单号查询
                QueryBuilder tempQuery = new TermQueryBuilder("wayBillNum",
                        wayBill.getWayBillNum());
                query.must(tempQuery);
            }
            if (StringUtils.isNoneBlank(wayBill.getSendAddress())) {
                //发货地的模糊查询
                //情况一:输入“北”是查询词条的一部分,使用模糊匹配词条查询
                QueryBuilder wildcardQuery = new WildcardQueryBuilder(
                        "sendAddress", "*" + wayBill.getSendAddress() + "*");
                
                //情况二:输入“北京市海淀区”是多个词条组合,进行分词后每个词条匹配查询
                QueryBuilder   queryStringQueryBuilder = new QueryStringQueryBuilder(wayBill.getSendAddress())
                                .field("sendAdress").defaultOperator(Operator.AND);
                
                //俩种情况取or关系
                BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                boolQueryBuilder.should(queryStringQueryBuilder);
                boolQueryBuilder.should(wildcardQuery);
                
                query.must(boolQueryBuilder);
            }
            if (StringUtils.isNoneBlank(wayBill.getRecAddress())) {
                // 收货地 模糊查询
                QueryBuilder wildcardQuery = new WildcardQueryBuilder(
                        "recAddress", "*" + wayBill.getRecAddress() + "*");
                query.must(wildcardQuery);
            }
            if (StringUtils.isNoneBlank(wayBill.getSendProNum())) {
                // 速运类型 等值查询
                QueryBuilder termQuery = new TermQueryBuilder("sendProNum",
                        wayBill.getSendProNum());
                query.must(termQuery);
            }
            if (StringUtils.isNoneBlank(wayBill.getSendProNum())) {
                // 速运类型 等值查询
                QueryBuilder termQuery = new TermQueryBuilder("sendProNum",
                        wayBill.getSendProNum());
                query.must(termQuery);
            }
            if (wayBill.getSignStatus() != null && wayBill.getSignStatus() != 0) {
                // 签收状态查询
                QueryBuilder termQuery = new TermQueryBuilder("signStatus",
                        wayBill.getSignStatus());
                query.must(termQuery);
            }

            SearchQuery searchQuery = new NativeSearchQuery(query);
            // Integer.MAX_VALUE:方便获取所有查询到的数据
            Pageable pageable = new PageRequest(0, Integer.MAX_VALUE);
            searchQuery.setPageable(pageable ); // 分页效果
            // 有条件查询 、查询索引库
            return wayBillIndexRepository.search(searchQuery).getContent();
        }
    }
Service层代码
package cn.itcast.bos.dao.index;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import cn.itcast.bos.domain.take_delivery.WayBill;
//多条件查询走的是缓存
public interface WayBillIndexRepository extends ElasticsearchRepository<WayBill, Integer> {

}
Dao层代码实现

最终实现效果:

 

 因为对POI的API了解不多,打印出来的Excel数据排版是手动调整的。

 

 

posted @ 2018-02-25 10:41  努力的小白菜  阅读(996)  评论(0编辑  收藏  举报