吴华辉
因为招投标需求对比单导出结构复杂,引入了myexcel工具实现自定义导出,文章介绍了单元格合并,颜色标记,数据遍历的语法供大家参考。
一些复杂格式的excel不适用于通用的表格工具导出,根据其他项目组的推荐使用了myexcel工具包
github地址:https://github.com/liaochong/myexcel
依赖添加
#Maven
<dependency>
<groupId>com.github.liaochong</groupId>
<artifactId>myexcel</artifactId>
<version>3.9.6</version>
</dependency>
#Gradle
compile group: 'com.github.liaochong', name: 'myexcel', version: '3.9.6'
#Ivy
<dependency org="com.github.liaochong" name="myexcel" rev="3.9.6"/>
模板导出
这里使用freemarker模板引擎(支持:beetl、groovy-templates、thymeleaf、velocity、enjoy)
1、依赖添加
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
2、模板示例
该模板是招投标系统中对比单导出中的通用类模板
<#-- 通用类模板 -->
<#-- 通用类模板 -->
<html>
<body>
<table style="text-align: center;vertical-align: middle;border-style:thin;">
<#-- 标题 -->
<#if titleName??>
<tr>
<th colspan="${biddingContrastBillSupplierVos?size * 4 + 7}">${titleName}</th>
</tr>
</#if>
<!-- 第一行 基础 -->
<tr>
<th rowspan="2">序号</th><!-- 纵向占两行 -->
<th rowspan="2">公司</th>
<th rowspan="2">物料名称</th>
<th rowspan="2">规格属性</th>
<th rowspan="2">要求品牌</th>
<th rowspan="2">单位</th>
<th rowspan="2">数量</th>
<#-- 循环遍历 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4">${(biddingContrastBillSupplierVo.supplierName)!''}</td><!-- 横向占三列 -->
</#list>
</tr>
<!-- 第二行 基础 -->
<#-- 循环遍历 -->
<tr>
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<th rowspan="1">单价(元)</th>
<th rowspan="1">总价(元)</th>
<th rowspan="1">品牌</th>
<th rowspan="1">备注</th>
</#list>
</tr>
<!-- 第三行 明细 -->
<#-- 循环遍历 -->
<#list bidPricingVos as bidPricingVo>
<tr>
<td rowspan="1">${bidPricingVo_index + 1} </td>
<td rowspan="1">${(bidPricingVo.companyName)!''}</td>
<td rowspan="1">${(bidPricingVo.skuName)!''}</td>
<td rowspan="1">${(bidPricingVo.attributeName)!''}</td>
<td rowspan="1">${(bidPricingVo.brand)!''}</td>
<td rowspan="1">${(bidPricingVo.unitName)!''}</td>
<td rowspan="1" string>${(bidPricingVo.quantity)!''}</td>
<#-- 循环遍历 -->
<#list bidPricingVo.biddingContrastBillSupplierDetailVos as biddingContrastBillSupplierDetailVo>
<#if biddingContrastBillSupplierDetailVo.min==1>
<td rowspan="1" style="background-color:#FFFF00"
string>${(biddingContrastBillSupplierDetailVo.price)!'/'}</td>
<#else>
<td rowspan="1" string>${(biddingContrastBillSupplierDetailVo.price)!'/'}</td>
</#if>
<td rowspan="1" string>${(biddingContrastBillSupplierDetailVo.priceTotal)!'/'}</td>
<td rowspan="1">${(biddingContrastBillSupplierDetailVo.brand)!'/'}</td>
<td rowspan="1">${(biddingContrastBillSupplierDetailVo.remark)!'/'}</td>
</#list>
</tr>
</#list>
<!-- 合计 -->
<tr>
<td colspan="7">合计</td><!-- 横向占6列 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4" string>${(biddingContrastBillSupplierVo.totalPrice)!'/'}</td><!-- 横向占3列 -->
</#list>
</tr>
<!-- 开票方式 -->
<tr>
<td colspan="7">开票方式</td><!-- 横向占6列 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4" string>${(biddingContrastBillSupplierVo.billingMethod)!'/'}</td><!-- 横向占3列 -->
</#list>
</tr>
<!-- 付款方式 -->
<tr>
<td colspan="7">付款方式</td><!-- 横向占6列 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4" string>${(biddingContrastBillSupplierVo.paymentMethod)!'/'}</td><!-- 横向占3列 -->
</#list>
</tr>
<!-- 交货时间 -->
<tr>
<td colspan="7">交货时间</td><!-- 横向占6列 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4" string>${(biddingContrastBillSupplierVo.deliveryTime)!'/'}</td><!-- 横向占3列 -->
</#list>
</tr>
<!-- 联系人 -->
<tr>
<td colspan="7">联系人</td><!-- 横向占6列 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4" string>${(biddingContrastBillSupplierVo.supplierContact)!'/'}</td><!-- 横向占3列 -->
</#list>
</tr>
<!-- 联系方式 -->
<tr>
<td colspan="7">联系方式</td><!-- 横向占6列 -->
<#list biddingContrastBillSupplierVos as biddingContrastBillSupplierVo>
<td colspan="4" string>${(biddingContrastBillSupplierVo.supplierPhone)!'/'}</td><!-- 横向占3列 -->
</#list>
</tr>
</table>
</body>
</html>
3、Workbook生成
由于产品要求对最低的价格进行颜色标记,则没有使用默认的样式。
public void export(Long fileId, HttpServletResponse response) {
//查询数据
BiddingContrastBillVo biddingContrastBillVo = biddingContrastBillService.export(fileId);
if (biddingContrastBillVo == null) {
throw new BidException("对比单信息不存在!");
}
Map<String, Object> dataMap = new HashMap<>(16);
// 标题 产品暂时没有要求
dataMap.put("titleName", biddingContrastBillVo.getFileName().split("\\.")[0]);
dataMap.put("bidPricingVos", biddingContrastBillVo.getBidPricingVos());
dataMap.put("biddingContrastBillSupplierVos", biddingContrastBillVo.getBiddingContrastBillSupplierVos());
// 模板
BidBillTemplateTypeEnum templateTypeEnum = BidBillTemplateTypeEnum.findByCode(biddingContrastBillVo.getTemplateType());
if (templateTypeEnum == null || StringUtil.isBlank(templateTypeEnum.getExportPath())) {
throw new BidException("导出模板不存在!");
}
try (ExcelBuilder excelBuilder = new FreemarkerExcelBuilder()) {
Workbook workbook = excelBuilder
.classpathTemplate(templateTypeEnum.getExportPath())
// .useDefaultStyle()
.build(dataMap);
AttachmentExportUtil.export(workbook, biddingContrastBillVo.getFileName(), response);
} catch (IOException e) {
e.printStackTrace();
}
}
注意的地方
1、如果使用默认样式,则无法会覆盖模板中定义的样式
2、如果使用自定义样式,并设置一些属性则可能升级poi版本