import labelmake from 'labelmake'
import type { Template } from 'labelmake/dist/types/type'
import opentype from 'opentype.js'
const generatePdf = async (): Promise<Blob> => {
const fontFamilyName = 'NotoSansCJKjp'
const fontStyleName = 'Medium'
const [font, basePdf] = await Promise.all([
fetch(`/fonts/otf/${fontFamilyName}-${fontStyleName}.otf`).then((res) =>
res.arrayBuffer(),
),
fetch('/base.pdf').then((res) => res.arrayBuffer()),
])
const schemas = [
{
顧客名: {
type: 'text',
position: {
x: 17,
y: 32.49,
},
width: 82.75,
height: 7.55,
alignment: 'center',
fontSize: 11,
characterSpacing: 0,
lineHeight: 1,
},
見積No: {
type: 'text',
position: {
x: 37,
y: 62.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
納期: {
type: 'text',
position: {
x: 37,
y: 68.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
納品場所: {
type: 'text',
position: {
x: 37,
y: 74.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
取引方法: {
type: 'text',
position: {
x: 37,
y: 80.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
有効期限: {
type: 'text',
position: {
x: 37,
y: 86.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
},
]
const inputs: Record<string, string>[] = [
{
見積No: '1234567890',
顧客名: 'テスト会社',
納期: 'データ入稿日より3営業日',
納品場所: '北海道',
取引方法: '原則としてご⼊⾦確認後の納品となります。',
有効期限: '2020年 2⽉ 29⽇',
},
]
const allStrings = inputs.reduce((acc, cur) => {
Object.keys(cur).forEach((key) => {
cur[key].split('').forEach((str) => {
acc.add(str)
})
return acc
}, acc)
return acc
}, new Set<string>())
const subset = generateSubsetFont(
{ font, familyName: fontFamilyName, styleName: fontStyleName },
allStrings,
)
const template: Template = {
schemas,
basePdf,
fontName: fontFamilyName,
}
const { buffer } = await labelmake({
template,
inputs,
font: {
[`${fontFamilyName}`]: {
data: subset,
subset: false,
},
},
})
const blob = new Blob([buffer], { type: 'application/pdf' })
return blob
}
const generateSubsetFont = (
fontObj: { font: ArrayBuffer; familyName: string; styleName: string },
useStrings: Set<string>,
): ArrayBuffer => {
const font = opentype.parse(fontObj.font)
const subsetGlyphs = font.stringToGlyphs([...useStrings].join(''))
const subset = new opentype.Font({
familyName: fontObj.familyName,
styleName: fontObj.styleName,
unitsPerEm: font.unitsPerEm,
ascender: font.ascender,
descender: font.descender,
glyphs: subsetGlyphs,
})
return subset.toArrayBuffer()
}