2020-10-16 11:30:59 +07:00
|
|
|
import {
|
|
|
|
CanvasElement,
|
|
|
|
Content,
|
|
|
|
TDocumentDefinitions
|
|
|
|
} from 'pdfmake/interfaces'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
import pdfMake from 'pdfmake/build/pdfmake'
|
2020-10-16 10:45:37 +07:00
|
|
|
|
|
|
|
export interface DataToPrint {
|
2020-10-16 11:30:59 +07:00
|
|
|
configs: {
|
|
|
|
title?: string
|
|
|
|
logoUrl?: string
|
|
|
|
headline?: string
|
|
|
|
columnsHeader: Array<Content>
|
|
|
|
}
|
|
|
|
data: {
|
|
|
|
header: any
|
|
|
|
items: any[]
|
|
|
|
summary: any
|
|
|
|
footer?: Array<Content>
|
|
|
|
}
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
const isInvoiceMasterRow = (i: number) => {
|
2020-10-16 11:30:59 +07:00
|
|
|
return i % 2 === 0 && i === 0
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
|
|
|
pdfMake.fonts = {
|
2020-10-16 11:30:59 +07:00
|
|
|
Khmer: {
|
|
|
|
normal: 'kh-battambang.ttf',
|
|
|
|
bold: 'kh-battambang.ttf',
|
|
|
|
italics: 'kh-battambang.ttf',
|
|
|
|
bolditalics: 'kh-battambang.ttf'
|
|
|
|
},
|
|
|
|
Roboto: {
|
|
|
|
normal:
|
|
|
|
'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Regular.ttf',
|
|
|
|
bold:
|
|
|
|
'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Medium.ttf',
|
|
|
|
italics:
|
|
|
|
'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Italic.ttf',
|
|
|
|
bolditalics:
|
|
|
|
'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-MediumItalic.ttf'
|
|
|
|
}
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
|
|
|
pdfMake.tableLayouts = {
|
2020-10-16 11:30:59 +07:00
|
|
|
invoiceMasterReport: {
|
|
|
|
paddingTop: function (i: number) {
|
|
|
|
return isInvoiceMasterRow(i) ? 1 : 0
|
2020-10-16 10:45:37 +07:00
|
|
|
},
|
2020-10-16 11:30:59 +07:00
|
|
|
paddingBottom: function (i: number) {
|
|
|
|
return isInvoiceMasterRow(i) ? 5 : 0
|
|
|
|
},
|
|
|
|
paddingLeft: function () {
|
|
|
|
return 2
|
|
|
|
},
|
|
|
|
paddingRight: function () {
|
|
|
|
return 2
|
|
|
|
},
|
|
|
|
fillColor: function (i: number) {
|
|
|
|
return i === 1 ? 'black' : '#e4e4e4'
|
|
|
|
},
|
|
|
|
vLineWidth: function () {
|
|
|
|
return 1
|
|
|
|
},
|
|
|
|
defaultBorder: false
|
|
|
|
},
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
invoiceNestedDetailReport: {
|
|
|
|
paddingLeft: function () {
|
|
|
|
return 1
|
2020-10-16 10:45:37 +07:00
|
|
|
},
|
2020-10-16 11:30:59 +07:00
|
|
|
paddingRight: function () {
|
|
|
|
return 0
|
2020-10-16 10:45:37 +07:00
|
|
|
},
|
2020-10-16 11:30:59 +07:00
|
|
|
paddingBottom: function () {
|
|
|
|
return 5
|
|
|
|
},
|
|
|
|
defaultBorder: false
|
|
|
|
},
|
|
|
|
invoiceLayout: {
|
|
|
|
paddingLeft: function () {
|
|
|
|
return 0
|
|
|
|
},
|
|
|
|
paddingRight: function () {
|
|
|
|
return 0
|
|
|
|
},
|
|
|
|
paddingTop: function () {
|
|
|
|
return 0.5
|
|
|
|
},
|
|
|
|
paddingBottom: function () {
|
|
|
|
return 0.5
|
|
|
|
},
|
|
|
|
hLineWidth: function (i: number, node: any) {
|
|
|
|
return i === 1 || i === node.table.body.length ? 0.2 : 0
|
|
|
|
},
|
|
|
|
vLineWidth: function () {
|
|
|
|
return 0
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
2020-10-16 11:30:59 +07:00
|
|
|
},
|
|
|
|
summaryInvoice: {
|
|
|
|
paddingLeft: function () {
|
|
|
|
return 0
|
|
|
|
},
|
|
|
|
paddingRight: function () {
|
|
|
|
return 0
|
|
|
|
},
|
|
|
|
paddingTop: function () {
|
|
|
|
return 5
|
|
|
|
},
|
|
|
|
paddingBottom: function () {
|
|
|
|
return 5
|
|
|
|
},
|
|
|
|
hLineColor: function (i) {
|
|
|
|
return i === 1 ? 'black' : '#e4e4e4'
|
|
|
|
},
|
|
|
|
vLineWidth: function () {
|
|
|
|
return 1
|
|
|
|
},
|
|
|
|
defaultBorder: false
|
|
|
|
}
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
|
|
|
const drawLine: (length?: number) => CanvasElement = (length = 292.26) => {
|
2020-10-16 11:30:59 +07:00
|
|
|
return {
|
|
|
|
type: 'line',
|
|
|
|
x1: 0,
|
|
|
|
y1: 0,
|
|
|
|
x2: length,
|
|
|
|
y2: 0,
|
|
|
|
lineWidth: 0.2
|
|
|
|
}
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
export const useDoc = (mockData: DataToPrint) => {
|
2020-10-16 11:30:59 +07:00
|
|
|
const [columns, setColumns] = useState<Array<any>>([])
|
|
|
|
const [body, setBody] = useState<Array<any>>([])
|
|
|
|
const [title, setTitle] = useState<Array<any>>([])
|
|
|
|
const [summary, setSummary] = useState<Array<any>>([])
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
useEffect(() => {
|
|
|
|
setColumns(mockData.configs.columnsHeader)
|
|
|
|
}, [])
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
useEffect(() => {
|
|
|
|
let temp: Array<any> = []
|
|
|
|
// eslint-disable-next-line array-callback-return
|
|
|
|
mockData.data.items.map((it: any) => {
|
|
|
|
let current: Array<any> = []
|
|
|
|
// eslint-disable-next-line array-callback-return
|
|
|
|
Object.values(it).map(function (key, index) {
|
|
|
|
const data = {
|
|
|
|
text: key,
|
|
|
|
fontSize: 9,
|
|
|
|
alignment: columns[index]?.alignment
|
|
|
|
}
|
|
|
|
current.push(data)
|
|
|
|
})
|
|
|
|
temp.push(current)
|
|
|
|
})
|
|
|
|
setBody([...temp])
|
|
|
|
}, [columns])
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
useEffect(() => {
|
|
|
|
let temp: Array<any> = []
|
|
|
|
// eslint-disable-next-line array-callback-return
|
|
|
|
Object.keys(mockData.data.header).map(function (key) {
|
|
|
|
const keyLabel = {
|
|
|
|
text: key + ' :',
|
|
|
|
fontSize: 9,
|
|
|
|
alignment: 'left'
|
|
|
|
}
|
|
|
|
const value = {
|
|
|
|
// @ts-ignore
|
|
|
|
text: mockData.data?.header[key],
|
|
|
|
fontSize: 9,
|
|
|
|
alignment: 'right'
|
|
|
|
}
|
|
|
|
temp.push([keyLabel, value])
|
|
|
|
})
|
|
|
|
setTitle([...temp])
|
|
|
|
}, [])
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
useEffect(() => {
|
|
|
|
const data = mockData.data.items.map((it: any) => {
|
|
|
|
return {
|
|
|
|
columns: [
|
|
|
|
Object.values(it).map(function (value, index) {
|
2020-10-16 10:45:37 +07:00
|
|
|
return {
|
2020-10-16 11:30:59 +07:00
|
|
|
text: value,
|
|
|
|
fontSize: 9,
|
|
|
|
width: '*',
|
|
|
|
alignment: columns[index]?.alignment
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
2020-10-16 11:30:59 +07:00
|
|
|
})
|
|
|
|
]
|
|
|
|
}
|
|
|
|
})
|
|
|
|
setBody([...data])
|
|
|
|
}, [])
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
useEffect(() => {
|
|
|
|
let temp: Array<any> = []
|
|
|
|
// eslint-disable-next-line array-callback-return
|
|
|
|
Object.keys(mockData.data.summary).map(function (key) {
|
|
|
|
const keyLabel = {
|
|
|
|
text: key + ' :',
|
|
|
|
fontSize: 9,
|
|
|
|
alignment: 'right'
|
|
|
|
}
|
|
|
|
const value = {
|
|
|
|
// @ts-ignore
|
|
|
|
text: mockData.data?.summary[key],
|
|
|
|
fontSize: 9,
|
|
|
|
alignment: 'center'
|
|
|
|
}
|
|
|
|
temp.push([keyLabel, value])
|
|
|
|
})
|
|
|
|
setSummary([...temp])
|
|
|
|
}, [])
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
const data: TDocumentDefinitions | any = {
|
|
|
|
content: [
|
|
|
|
mockData.configs.logoUrl && {
|
|
|
|
alignment: 'center',
|
|
|
|
image: mockData.configs.logoUrl,
|
|
|
|
width: 100,
|
|
|
|
height: 75,
|
|
|
|
style: 'header',
|
|
|
|
fontSize: 23,
|
|
|
|
bold: true,
|
|
|
|
margin: [0, 10]
|
|
|
|
},
|
|
|
|
mockData.configs.title && {
|
|
|
|
alignment: 'center',
|
|
|
|
text: mockData.configs.title,
|
|
|
|
style: 'header',
|
|
|
|
fontSize: 8,
|
|
|
|
bold: true,
|
|
|
|
margin: [0, 10]
|
|
|
|
},
|
|
|
|
mockData.configs.headline && {
|
|
|
|
alignment: 'center',
|
|
|
|
text: mockData.configs.headline,
|
|
|
|
fontSize: 18,
|
|
|
|
bold: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
layout: 'noBorders',
|
|
|
|
fontSize: 9,
|
|
|
|
table: {
|
|
|
|
widths: '*',
|
|
|
|
body: [...title]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
layout: 'invoiceMasterReport',
|
|
|
|
table: {
|
|
|
|
widths: '*',
|
|
|
|
body: [mockData.configs.columnsHeader]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
layout: 'invoiceNestedDetailReport',
|
|
|
|
table: {
|
|
|
|
widths: '*',
|
|
|
|
body: [...body]
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
2020-10-16 11:30:59 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
columns: [
|
|
|
|
{
|
|
|
|
canvas: [drawLine()]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
layout: 'summaryInvoice',
|
|
|
|
table: {
|
|
|
|
widths: ['*', '*'],
|
|
|
|
body: [...summary]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
columns: [
|
|
|
|
{
|
|
|
|
canvas: [drawLine()]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
mockData.data.footer?.map((it) => {
|
|
|
|
return it
|
|
|
|
})
|
|
|
|
],
|
|
|
|
pageSize: { width: 302.26, height: 'auto' },
|
|
|
|
pageOrientation: 'portrait',
|
|
|
|
pageMargins: [5, 5, 5, 5],
|
|
|
|
styles: {
|
|
|
|
header: {
|
|
|
|
color: '#2ac4e6'
|
|
|
|
}
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|
2020-10-16 11:30:59 +07:00
|
|
|
}
|
2020-10-16 10:45:37 +07:00
|
|
|
|
2020-10-16 11:30:59 +07:00
|
|
|
return pdfMake.createPdf(data)
|
2020-10-16 10:45:37 +07:00
|
|
|
}
|