使用接口适配模式做报表导出

目录

生产中时常会遇到做报表导出的功能,让我们一步一步的来分析怎么做一个报表,

cell+row+sheet

1。 cell : 报表的 最小单位值是 cell : 有值,类型,样式,生产中我们可以实现在 resource中 放入已经调好的样式,于是我们要做的就是向excel中添值,为了更好的添值,我们为 每个cell 添加一个 索引 属性

public class Cell {
    private Object value;
    private int colIndex; //显示的列索引
    private String dataType; //int, string, date, double
}
  1. 由cell 构成的是一个row行,每一个row 又有 cell,显不显示
    所以
public class Row {
    private String indicator;
    private Cell[] cells = null; //行值
    private boolean formular = false; 
}
  1. 由row又会构成sheet,可能会有很多sheet ,当然 也会有 一年 有12个月,于是一个 excel文件中含有 12 个sheet,于是我们理所当然要 配置 每一个sheet 的 code + 名字+ 是否复制
public class Sheet {
    private String code; //编码
    private String name; //Sheet名称
    private boolean clone = false; //是否复制
}

导出的逐步分解

  1. 首先 对导出动作做一个抽象,导出的 是 sheet,sheet 都需要 数据集
public interface IExcelReportSource { 
     * 获取Sheet定义 肯定是共有的
    public Sheet[] getSheets(Map<String, Object> context);

     * 获取当前Sheet需要的数据集  这个肯定是 都不相同
    public List<Row> getSheetRows(Map<String, Object> context, Sheet sheet);
} 

这时 ,我有些excel 可能只需要sheet,有些可能具体的数据,所以我的实现类,只需要接口中的某些方法的实现,所以 我需要写一个 接口适配器,

public abstract class AbstractReportSourceService implements IExcelReportSource {
  @Override
    public Sheet[] getSheets(Map<String, Object> context) {
     // 这里可以是 你从 其他地方搞来的 数据组装的 sheet
}

}

这个抽象类 重写的getsheets() 可以公用,具体的实现类看可以有很多个

@Component("LSHROSWeekReportSource")
public class souce1  extends AbstractReportSourceService {
 @Override
    public List<Row> getSheetRows(Map<String, Object> context, Sheet sheet) {
                            }
}

或者

@Component("SaleMonthlyReportSource")
public class source2  extends AbstractReportSourceService {
    @Override
    public List<Row> getSheetRows(Map<String, Object> context, Sheet sheet) {

         }

}

2。 导出的报表ExcelReportContext 需要
模板名字+文件名+导出动作+起止cell

public class ExcelReportContext {
    private String template; // 模板名字
    private String fileName;  // 文件名字
    private Map<String, Object> params = new HashMap<>();// 这就是 参数
    private IExcelReportSource source;
    private boolean staticSheet;   
    private int clonableSheet = 0;
    private int startCellIndex = 0;
    private int endCellIndex = 0;
    private boolean autoRowExtended = false;
 public ExcelReportContext addParam(String name, Object value) {
        params.put(name, value); 
        return this;
    }

    }

3。 导出的service做一个抽象,

public interface IExcelReportService {

     * 导出Excel到outputStream   本地  导出 
    public void export(ExcelReportContext context, OutputStream os) throws Exception;


     * 导出Excel到Response   导出到 页面 
    public void export(ExcelReportContext context, HttpServletResponse response) throws Exception;
}

实现类

@Component("ExcelReportService")
public class ExcelReportServiceImpl implements IExcelReportService { 
    @Override
    public void export(ExcelReportContext context, OutputStream os) throws Exception {
        XSSFWorkbook xWorkbook = this.getWorkbook(context); 
        xWorkbook.write(os);

        xWorkbook = null;
    }

实际使用

根据 注入的 resource ,确定 数据集从哪里来,

@Service
@Transactional
public class ReportServiceImpl implements ReportService {
    private Logger logger = LoggerFactory.getLogger(ReportServiceImpl.class);

    @Autowired
    private IExcelReportService excelReportService;

    @Resource(name = "SaleMonthlyReportSource")
    private IExcelReportSource source1;

    @Resource(name = "LSHROSWeekReportSource")
    private IExcelReportSource source2;

  public void getSalesManagerReport(String username, String year, HttpServletResponse response) {
        try {
            ExcelReportContext context = new ExcelReportContext();
            context.setTemplate("templates/销售管理报表模板.xlsx")
                    .setFileName(year + "年销售管理报表.xlsx")
                    .setSource(saleMonthlyReportSource)
                    .setStaticSheet(false)
                    //.setClonableSheet(2)  读取第三个  sheet(不写默认为第一个sheet)
                    .addParam("username", username).addParam("year", year);

            excelReportService.export(context, response);
        } catch (Exception exc) {
            logger.error("报表[销售管理报表]导出异常。", exc);
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值