fix(planting-service): 使用自定义外观流嵌入签名图片

- setImage 无法正确渲染签名到按钮字段
- 手动创建 XObject Form 外观流
- 计算图片缩放和居中位置
- 设置 widget 的 NormalAppearance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-26 05:35:58 -08:00
parent bdeff3b372
commit 86103e4c4d
1 changed files with 48 additions and 4 deletions

View File

@ -381,11 +381,55 @@ export class PdfGeneratorService {
try {
const form = pdfDoc.getForm();
const signatureButton = form.getButton(FORM_FIELDS.SIGNATURE);
signatureButton.setImage(signatureImage);
this.logger.log('Signature embedded using form field');
} catch {
// 获取按钮的 widget 和尺寸
const widgets = signatureButton.acroField.getWidgets();
if (widgets.length > 0) {
const widget = widgets[0];
const rect = widget.getRectangle();
const { width: fieldWidth, height: fieldHeight } = rect;
// 计算图片缩放尺寸(保持宽高比,适应字段大小)
const imgDims = signatureImage.scale(1);
let scale = Math.min(fieldWidth / imgDims.width, fieldHeight / imgDims.height);
const scaledWidth = imgDims.width * scale;
const scaledHeight = imgDims.height * scale;
// 计算居中位置
const x = (fieldWidth - scaledWidth) / 2;
const y = (fieldHeight - scaledHeight) / 2;
// 创建外观流内容
const appearanceStream = `q ${scaledWidth} 0 0 ${scaledHeight} ${x} ${y} cm /Img Do Q`;
// 创建 XObject Form 作为外观
const context = pdfDoc.context;
const imageXObjectName = 'Img';
const Resources = context.obj({
XObject: { [imageXObjectName]: signatureImage.ref },
});
const appearanceStreamRef = context.register(
context.stream(appearanceStream, {
Type: 'XObject',
Subtype: 'Form',
FormType: 1,
BBox: [0, 0, fieldWidth, fieldHeight],
Resources,
}),
);
// 设置外观到 widget
widget.setNormalAppearance(appearanceStreamRef);
this.logger.log('Signature embedded using custom appearance stream');
} else {
throw new Error('No widgets found for signature button');
}
} catch (error) {
// 如果没有签名按钮字段,回退到坐标方式
this.logger.log('Signature button field not found, using coordinates');
this.logger.log(`Signature button field error: ${error.message}, using coordinates`);
this.embedSignatureByCoordinates(pdfDoc, signatureImage);
}
}