如何在 PDFKIT 中显示封闭的字母数字 (⒮, ①) 或转换为普通字母数字字符串
How to Display Enclosed Aphanumeric (⒮, ①) in PDFKIT or convert to Normal Alphanumeric string
我正在使用 PDFKIT 在 Node JS 上生成 PDF。
但是,无法生成封闭的字母数字(如⒮、①等)。
我查看了 Google fonts,NotoSansCJKjp-Regular 似乎支持封闭的字母数字。所以我认为可能是这个库不支持封闭的字母数字。
有没有我可以在 PDF 上生成封闭的字母数字或
有什么方法可以将其转换为常规字母数字?
例如⒮=>(s),①=>1
感谢您的帮助!
下面是我的代码。
export class CreateVoucherUsecase {
private doc = new PDFDocument({ size: 'A4', margin: 20 });
async createAirTicketVoucher(res: Response, id: number): Promise<void> {
const hotel = await new AirTicketRepository().findById(id);
if (hotel === null) throw new NotFoundError('airticket voucher pdf: airticket not found: id = ' + id);
this.setFontRegular();
this.writeInfo(res, info);
this.doc.end();
}
private drawHorizontalLine(params: { length: number; color?: string; width?: number; dy?: number }): void {
this.doc
.moveTo(this.doc.x, this.doc.y + (params.dy ?? 0))
.lineWidth(params.width ?? 1)
.lineTo(this.doc.x + params.length, this.doc.y + (params.dy ?? 0))
.stroke(params.color ?? 'blue');
}
private getAsset(path: string): string {
return require.main?.path.replace('dist', path) ?? '';
}
private setFont(style: string): void {
this.doc.font(this.getAsset(`fonts/NotoSansCJKjp-${style}.ttf`));
}
private setFontRegular(): void {
this.setFont('Regular');
}
private setFontBold(): void {
this.setFont('Bold');
this.doc.fontSize(12);
}
/** write text. not update indent */
private text(value: string, x?: number, y?: number) {
const originalX = this.doc.x;
return this.doc.text(value, x, y).text('', originalX);
}
private writeH2(text: string): void {
this.setFontBold();
this.doc
.moveDown()
.fillColor('black')
.text(text, undefined, this.doc.y + 10);
this.setFontRegular();
}
private writeLink(link: string, length: number): void {
this.doc.fillColor('blue').text(link);
this.drawHorizontalLine({ length: length, dy: SPACE });
}
private writeTable(labels: string[], values: (string | number)[]): void {
const tableWidth = 480;
const column1Width = 150;
const marginLeft = 3;
for (let i = 0; i < labels.length; i++) {
const [leftTopX, leftTopY] = [this.doc.x, this.doc.y];
this.text(labels[i], leftTopX + marginLeft);
const [newX, newY] = [this.doc.x, this.doc.y];
this.text(convert2String(values[i].toString()), leftTopX + column1Width + marginLeft, leftTopY);
this.text('', newX, newY);
const [rectX, rectY, rectHeight] = [leftTopX, leftTopY + SPACE, this.doc.y - leftTopY];
if (i < labels.length)
this.doc
.lineWidth(1)
.rect(rectX, rectY, tableWidth, rectHeight)
.stroke('black')
.rect(rectX, rectY, column1Width, rectHeight)
.fillOpacity(0.2)
.fillAndStroke('#AFEEEE', 'black')
.fillOpacity(1)
.fillColor('black');
}
}
private writeInfo(res: Response, info: Info): void {
...........
}
}
当我使用下面的normalization method.
问题就解决了
String.normalize('NFKC')
我正在使用 PDFKIT 在 Node JS 上生成 PDF。 但是,无法生成封闭的字母数字(如⒮、①等)。
我查看了 Google fonts,NotoSansCJKjp-Regular 似乎支持封闭的字母数字。所以我认为可能是这个库不支持封闭的字母数字。
有没有我可以在 PDF 上生成封闭的字母数字或 有什么方法可以将其转换为常规字母数字?
例如⒮=>(s),①=>1
感谢您的帮助!
下面是我的代码。
export class CreateVoucherUsecase {
private doc = new PDFDocument({ size: 'A4', margin: 20 });
async createAirTicketVoucher(res: Response, id: number): Promise<void> {
const hotel = await new AirTicketRepository().findById(id);
if (hotel === null) throw new NotFoundError('airticket voucher pdf: airticket not found: id = ' + id);
this.setFontRegular();
this.writeInfo(res, info);
this.doc.end();
}
private drawHorizontalLine(params: { length: number; color?: string; width?: number; dy?: number }): void {
this.doc
.moveTo(this.doc.x, this.doc.y + (params.dy ?? 0))
.lineWidth(params.width ?? 1)
.lineTo(this.doc.x + params.length, this.doc.y + (params.dy ?? 0))
.stroke(params.color ?? 'blue');
}
private getAsset(path: string): string {
return require.main?.path.replace('dist', path) ?? '';
}
private setFont(style: string): void {
this.doc.font(this.getAsset(`fonts/NotoSansCJKjp-${style}.ttf`));
}
private setFontRegular(): void {
this.setFont('Regular');
}
private setFontBold(): void {
this.setFont('Bold');
this.doc.fontSize(12);
}
/** write text. not update indent */
private text(value: string, x?: number, y?: number) {
const originalX = this.doc.x;
return this.doc.text(value, x, y).text('', originalX);
}
private writeH2(text: string): void {
this.setFontBold();
this.doc
.moveDown()
.fillColor('black')
.text(text, undefined, this.doc.y + 10);
this.setFontRegular();
}
private writeLink(link: string, length: number): void {
this.doc.fillColor('blue').text(link);
this.drawHorizontalLine({ length: length, dy: SPACE });
}
private writeTable(labels: string[], values: (string | number)[]): void {
const tableWidth = 480;
const column1Width = 150;
const marginLeft = 3;
for (let i = 0; i < labels.length; i++) {
const [leftTopX, leftTopY] = [this.doc.x, this.doc.y];
this.text(labels[i], leftTopX + marginLeft);
const [newX, newY] = [this.doc.x, this.doc.y];
this.text(convert2String(values[i].toString()), leftTopX + column1Width + marginLeft, leftTopY);
this.text('', newX, newY);
const [rectX, rectY, rectHeight] = [leftTopX, leftTopY + SPACE, this.doc.y - leftTopY];
if (i < labels.length)
this.doc
.lineWidth(1)
.rect(rectX, rectY, tableWidth, rectHeight)
.stroke('black')
.rect(rectX, rectY, column1Width, rectHeight)
.fillOpacity(0.2)
.fillAndStroke('#AFEEEE', 'black')
.fillOpacity(1)
.fillColor('black');
}
}
private writeInfo(res: Response, info: Info): void {
...........
}
}
当我使用下面的normalization method.
问题就解决了String.normalize('NFKC')