空白键|基于Excel和Java自动化工作流程:发票生成器示例

对于销售人员 , 使用Excel创建发票是很常见的 。 但是该过程通常涉及许多容易出错的手动操作 , 例如输入数据 , 复制/粘贴等 。 如何实现一个可以将数据从数据库自动填充到发票Excel模板中 , 而无需再辛苦手动输入 , 从繁重的手动录入中解脱出来 , 并且避免认为错误这是每个人迫切的需求 。 虫虫一直奉行理念:真正的自动化是解决用户痛点问题 , 把繁重人工劳动释放出来 。 本文我们就介绍一个老外的利用Java编写自动化程序实现自动化发票生成器的案例 , 案例中创建了一个Web应用程序Invoice Builder , 并利用Excel模版文件 , Java和Keikai将这种手动发票录入过程转换为集成的自动化过程 。
总体架构体系图下图显示了发票生成器应用程序的体系图:
空白键|基于Excel和Java自动化工作流程:发票生成器示例
文章图片
:keikai电子表格 。
:水平布置其子组件 , 垂直布置组件 。
:带有边框和标题的组件分组 。
每个标签都支持一些属性 , 例如:
src:指定要导入到Keikai的Excel文件路径 。
maxVisibleRows:控制keikai在浏览器中渲染工作表时的最大可见行数 。
控制器要为页面指定控制器 , 只需在apply属性处指定了全限定的类名:
...然后 , 该控制器可以控制其子组件 。 我通常在页面的根组件上指定一个控制器 。
自动填充客户现在可以显示电子表格和源文件 , 接着需要将数据自动填充到表 。
源Excel文件仅包含一个空客户表 , 其表样式如列名和标题颜色 。 这里的一件好事是 , 这个Excel文件是由我的销售人员使用Excel创建的-他更清楚自己想在此表中看到的内容 。
空白键|基于Excel和Java自动化工作流程:发票生成器示例从服务类加载客户列表 , 并将列表填充到表中:
private void populateCustomers() {List customers = CustomerService.getCustomerList();Range startingCell = customerTable.toCellRange(0, 1); //the 1st column is for checkboxfor (String[] c : customers) {RangeHelper.setValuesInRow(startingCell, c);startingCell = startingCell.toShiftedRange(1, 0);}}CustomerService 也可以是您所提供的数据实体的任何Java类 。
setValuesInRow() 用字符串数组(例如B2 , C2 , D2 ...)一行一行地填充多个单元格
toShiftedRange(1, 0)转移startingCell到下一行 。
用命名范围填充数据将数据填充到电子表格UI时 , 需要指定要将数据填充到的目标单元格 。 选择命名范围是因为它是一种灵活的方法 。
首先 , 创建几个指定范围中的每个模板文件例如Name , Phone和Email客户详细信息 。 最终用户选择客户和产品后 , 控制器将每一行提取为地图 。 索引是标题 , 该值是对应的单元格值 , 例如
{Name: Debra, Phone: 338-8777, Email: debra@...} 。
然后 , 从所选模板中克隆发票表 , 并将客户详细信息填充到相应的命名范围中 。
空白键|基于Excel和Java自动化工作流程:发票生成器示例@Listen(org.zkoss.zk.ui.event.Events.ON_CLICK + "=#create")public void createInvoice() {...Book invoiceBook = Books.createBook("invoice.xlsx");for (Map customer : selectedCustomers) {Sheet invoiceSheet = Ranges.range(invoiceBook).cloneSheetFrom(customer.get("CompanyName").toString(), templates.get(getSelectedTemplateFileName()).getSheetAt(0));populateNamedRange(generateAgentData(), invoiceSheet);populateNamedRange(customer, invoiceSheet);...}...}private void populateNamedRange(Map fieldMap, Sheet sheet) {List namedRanges = Ranges.getNames(sheet);fieldMap.forEach((name, value) -> {if (namedRanges.contains(name)) {Range range = Ranges.rangeByName(sheet, name);range.setCellValue(value);}});}


推荐阅读