Index
概要
之前我们给大家演示了如何预览kintone中excel数据的自定义开发(kintone excel预览插件)
大家都觉得很有用。但是excel的需求实在太多,还有一些用户来留言,希望能实现将kintone数据直接生成excel。
那这次我们就来研究下这种需求如何实现吧。
需求
我们经常会有这样的问题:虽然通过kintone创建了订单,送货单,合同类应用,实现了无纸化办公,但是有时候还是需要能将数据打印出来提供给客户,或者存档等。
虽然kintone自带打印功能,但是无法对打印样式进行一个编排。这时候我们可以设想,如果有这么一个开发,只需要我们提供excel模版,然后能自动填入kintone上的应用数据到这个excel模版,
并且可以下载打印。那是不是就完美的满足了我们的需求。
演示效果
kintone应用准备
导入应用
导入我们事先准备好的模版应用:excel生成
添加数据
添加一条数据。其中“模版”字段使用源码中的template.xlsx
开发
开发使用到的库
之前excel预览使用的是sheetjs,这次我们使用另一个比较常用的excel库exceljs。他同样比较受欢迎。当然使用sheetjs也是能实现的。
exceljs也是符合双端规范的一个库。所以他也提供了Browserify的导入方式
cdn地址:https://cdn.jsdelivr.net/npm/exceljs@4.3.0/dist/exceljs.min.js
代码说明
绑定kintone事件
kintone.events.on('app.record.detail.show', (event) => { const record = event.record const file = record.Template.value if (file.length > 0) { if (checkXls(file[0].name)) { loadDownload(file[0], record) } } return event })
判断是否为excel文件
const checkXls = (file) => { const reg = /\.xl(s[xmb]|t[xm]|am|s)$/g return reg.test(file) }
读入excel模版数据
const readWorkbookFromRemoteFile = async (url, record) => { const xhr = new XMLHttpRequest() xhr.open('get', url, true) xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') xhr.responseType = 'arraybuffer' xhr.onload = async (e) => { if (xhr.status == 200) { const blob = await FillData(xhr, record) const a = document.createElement('a') const url = window.URL.createObjectURL(blob) a.href = url a.download = 'new.xlsx' a.click() window.URL.revokeObjectURL(url) } } xhr.send() }
将kintone数据转化成exceljs的Workbook对象
const FillData = async (xhr, record) => { let data = new Uint8Array(xhr.response) const workbook = new ExcelJS.Workbook() await workbook.xlsx.load(data) const worksheet = workbook.getWorksheet('Sheet1') const CustomerNameCell = worksheet.getCell('C4') const AddressCell = worksheet.getCell('C7') const ContactCell = worksheet.getCell('C6') const DepartmentCell = worksheet.getCell('C5') const NoteCell = worksheet.getCell('C8') const PhoneCell = worksheet.getCell('H6') const ReceiveDateCell = worksheet.getCell('H5') const SnCell = worksheet.getCell('H4') const CreatorCell = worksheet.getCell('B18') CustomerNameCell.value = record.CustomerName.value AddressCell.value = record.Address.value ContactCell.value = record.Contact.value DepartmentCell.value = record.Department.value NoteCell.value = record.Note.value PhoneCell.value = record.Phone.value ReceiveDateCell.value = record.ReceiveDate.value SnCell.value = record.Sn.value CreatorCell.value = record.Creator.value let indexLine = 11 for (const row of record.Table.value) { const rowValue = row.value const rowMap = { 0: 'A', 1: 'D', 2: 'F', 3: 'H', } Object.keys(rowValue).forEach((key, index) => { const cellField = rowMap[index] + indexLine const cell = worksheet.getCell(cellField) cell.value = rowValue[key].value }) indexLine++ } const uint8Array = await workbook.xlsx.writeBuffer() const blob = new Blob([uint8Array], { type: 'application/octet-binary', }) return blob }
生成下载按钮,下载excel
const loadDownload = (fileInfo, record) => { if (document.getElementById('downloadButton') !== null) { return } const downloadButton = document.createElement('button') downloadButton.id = 'downloadButton' downloadButton.innerText = '一键生成excel' downloadButton.onclick = () => { const fileUrl = '/k/v1/file.json?fileKey=' + fileInfo.fileKey readWorkbookFromRemoteFile(fileUrl, record) } kintone.app.record.getHeaderMenuSpaceElement().appendChild(downloadButton) }
代码下载
注意事项
本示例代码不保证其运行。
我们不为本示例代码提供技术支持。
回复(2)
关于excel 模版中vba代码丢失的问题。查询了下,貌似是因为这个excel导出并且重命名导致的。
“从excel2007开始有了区分,.xlsm是含有VBA代码(宏)的,.xlsx是不含VBA代码(宏)的,默认是.xlsx,如果不想含有代码,可以保存为xlsx,即可自动删除其中VBA代码”
那样的话可以试下,不改变其后缀扩展名,只是改名字。
比如对其重命名时,这边只是简单的重命名为“new.xlsx” 而实际上,你可以使用以下代码,将其重命名为“new-”开头加上原来excel模版名的方式来导出。试下是否能解决你的问题。
const file = record[templateField];
const newFileName =
"new-"
+ file.value[0].name;
谢谢大佬赐教
唯一不足的是,excel横版中的vba代码将不会被保留