多态工厂通过Exporter<T>接口解耦“生成什么格式”与“怎么生成”,统一导出契约并屏蔽格式差异;各格式独立实现互不影响,工厂按HTTP头或路径后缀动态装配,支持热注册;复杂报表结构通过组合ReportLayoutStrategy策略模式灵活适配。

多态工厂在复杂报表生成与导出中,核心是把“生成什么格式”和“怎么生成”彻底解耦——调用方只面向统一接口,具体实现由运行时自动匹配,不写一个 if-else。
统一导出契约,屏蔽格式差异
定义一个抽象的 Exporter<T> 接口,声明所有导出行为的最小公共集:
- export(List<T> data, OutputStream out):执行实际写入逻辑
-
getContentType():返回 HTTP 响应头所需的 MIME 类型(如
application/pdf) -
getFileExtension():返回文件后缀(如
pdf、xlsx、csv)
这个接口不关心底层用的是 POI、iText 还是 JXLS,也不管是否要分页、加水印或填 AcroForm 表单。它只承诺:“我能把数据导出来”。
各格式独立实现,互不影响
每种报表格式对应一个具体实现类,各自封装技术细节:
立即学习“Java免费学习笔记(深入)”;
- ExcelExporter:基于 Apache POI 或 JXLS 模板,支持样式、合并单元格、动态列;大数据量可用 SXSSFWorkbook 流式写入
- PdfExporter:用 iText7 构建表格+段落,或加载预设 PDF 模板填充 AcroForm 字段;支持页眉页脚、数字签名区域预留
- HtmlExporter:生成语义化 HTML 表格,适配打印样式,可嵌入 Chart.js 图表脚本
- CustomPdfWithChartExporter:继承 PdfExporter,额外集成 JFreeChart 渲染折线图并嵌入 PDF 页面
新增一种格式(比如 Word 或 ZIP 打包多格式),只需新增一个类实现 Exporter 接口,无需动已有代码。
工厂按需装配,支持动态识别
ExporterFactory 不是硬编码判断,而是通过轻量映射 + 可扩展机制选型:
- 根据 HTTP 请求的
Accept头(如application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)识别意图 - 或解析请求路径后缀(
/report/export.pdf→pdf) - 内部用
Map<String, Supplier<Exporter<?>>>注册,如:"xlsx" → () -> new ExcelExporter<>() - 支持运行时热注册(例如插件机制加载第三方导出器)
Controller 层完全无感知:Exporter<SaleRecord> exporter = ExporterFactory.getExporter(format); exporter.export(data, out);
应对复杂报表结构的延伸设计
当报表本身结构多变(如销售汇总 vs 审计附注),可在 Exporter 内部组合策略模式:
- 定义 ReportLayoutStrategy 接口,不同业务场景提供不同布局实现(
StandardLayout/AuditLayout) - Exporter 构造时注入对应策略,或根据参数动态选择
- 导出主流程不变,仅 layout.render() 部分替换,保持多态链完整
这样,同一 PDF 导出器既能输出标准销售报表,也能按审计规范生成带验证说明和签名栏的版本,复用基础能力,隔离业务逻辑。


















