fastlion-amis
Version:
一种MIS页面生成工具
168 lines (154 loc) • 6.53 kB
text/typescript
import { flatMap } from "lodash"
import { combineCell, getCellValue } from "../../../../../store/utils/commonTableFunction"
import { calcFn, sortFn } from "../../../../../utils/utils"
import { ReportOptionValues, ReportTableValues } from "./types"
export const createHtml = (options: ReportOptionValues & { tableWidth: number }, tableColumns: ReportTableValues[], tableHeadRows: any[], tableData: any[], range: [number, number], isLastTask: boolean) => {
const [start, end] = range
const showColumns = tableColumns.filter(column => column.printType != 'none' && column.width != 0 && column.width != undefined)
let width = 0
let idx = showColumns.length
for (let i = 0; i < showColumns.length; i++) {
const column = showColumns[i]
width += column.width!
if (width > options.tableWidth) {
idx = i
break
}
}
const columns = showColumns.slice(0, idx)
const table = document.createElement('table')
table.style.margin = '0 auto'
table.style.borderCollapse = 'collapse'
table.style.tableLayout = 'fixed'
table.style.border = `${Math.max(2, options.borderWidth ?? 2)}px solid #333333`
table.style.wordBreak = 'break-all'
table.style.fontSize = `${options.contentFontSize}px`
table.style.fontFamily = options.contentFontFamily
table.style.width = `${width}px`
table.setAttribute('border', options.lineWidth.toString())
// table.setAttribute('style', `font-size: 13px; width: ${width}px; border-collapse:collapse; margin: 0 auto; border: ${options.borderWidth}px solid; table-layout: fixed;`)
const colgroup = document.createElement('colgroup')
columns.forEach(column => {
const col = document.createElement('col')
if (column.width) {
col.style.setProperty('width', `${column.width * 3.78}px`)
}
colgroup.appendChild(col)
})
table.appendChild(colgroup)
const thead = document.createElement('thead')
thead.style.display = 'table-header-group'
for (let i = 0; i < tableHeadRows.length; i++) {
const headRow = tableHeadRows[i]
const tr = document.createElement('tr')
headRow.slice(0, idx).forEach((item: any) => {
const temp = item.rowspan == tableHeadRows.length - i
const th = document.createElement('th')
th.textContent = temp ? item.column.label : item.label
th.colSpan = item.colspan
th.rowSpan = item.rowspan
th.style.padding = `${options.rowPadding}px ${options.colPadding}px`
tr.appendChild(th)
})
thead.appendChild(tr)
}
table.appendChild(thead)
const sortColumnNames = flatMap(columns ?? [], column => column.sort != 'none' ? { name: column.name, func: column.sort } : [])
const tbody = document.createElement('tbody')
const data = sortArray(tableData.slice(start, end), sortColumnNames).map(item => ({ ...item, rowSpans: {} }))
combineCell(data, columns.filter(item => item.combined))
for (let i = 0; i < data.length; i++) {
const row = data[i]
const tr = document.createElement('tr')
for (let j = 0; j < columns.length; j++) {
const column = columns[j]
const rowspan = row.rowSpans[column.name]
if (rowspan === 0) continue
const td = document.createElement('td')
const value = getCellValue(row[column.name], column)
td.textContent = value
td.rowSpan = rowspan || 1
td.style.textAlign = column.align
td.style.padding = `${options.rowPadding}px ${options.colPadding}px`
tr.appendChild(td)
}
tbody.appendChild(tr)
}
const hasStatistic = columns.some(column => column.statistic != 'none')
const dataTypeArr = ['number', 'static-number', 'input-number', 'progress', 'static-progress']
if (isLastTask && !options.countAllPage && hasStatistic) {
const tr = document.createElement('tr')
for (let j = 0; j < columns.length; j++) {
const td = document.createElement('td')
if (j == 0) {
td.textContent = '合计:'
}
const column = columns[j]
if (column.statistic == 'Sum') {
if (dataTypeArr.includes(column.type) || column.pristine.isNumerical) {
const value = calcFn('sum', column.name, tableData)
td.textContent = getCellValue(value, column)
} else {
const value = data.filter(item => item[column.name]).length
td.textContent = value.toString()
}
td.style.textAlign = column.align
}
tr.appendChild(td)
}
tbody.appendChild(tr)
}
table.appendChild(tbody)
if (options.countAllPage && hasStatistic) {
const tfoot = document.createElement('tfoot')
const tr = document.createElement('tr')
columns.forEach((column, index) => {
const td = document.createElement('td')
if (index == 0) { td.textContent = '合计:'}
if (column.statistic == 'Sum') {
if (dataTypeArr.includes(column.type) || column.pristine.isNumerical) {
const value = calcFn('sum', column.name, tableData)
td.textContent = getCellValue(value, column)
} else {
const value = data.filter(item => item[column.name]).length
td.textContent = value.toString()
}
td.style.textAlign = column.align
}
tr.appendChild(td)
})
tfoot.appendChild(tr)
table.append(tfoot)
}
return table.outerHTML
}
const sortArray = (datas: any[], columns: { name: string, func: 'asc' | 'desc' }[]) => {
if (columns.length > 0) {
const column = columns.pop()
if (column) {
const name = column.name
const func = column.func
datas = datas.sort((a, b) => {
const valueA = a[name]
const valueB = b[name]
return sortFn(valueA, valueB, func)
})
sortArray(datas, columns)
}
}
return datas
}
// fontsize lineheight
// 13px 14.8317
// 14px 15.97
// 15px 17.11
// 16px 18.25
// 17px 19.39
// 1px = (25.4 / 96)mm
// avg 1.1406994586296058
export const getCountOfPage = (tableHeight: number, fontSize: number, padding: number) => {
const unit = 25.4 / 96
const lineHeight = (((1 + fontSize) * 1.1406994586296058) + (padding * 2)) * unit
const countOfPage = Math.floor(tableHeight / lineHeight)
return countOfPage
}