1. 程式人生 > >使用介面適配模式做報表匯出

使用介面適配模式做報表匯出

目錄

生產中時常會遇到做報表匯出的功能,讓我們一步一步的來分析怎麼做一個報表,

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);
        }
    }