fix(signing-pdf): 修复导出 PDF 丢失 flex 容器内容
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
* 直接截图既截不全、版面也会跟着变;
|
||||
* ② 固定页眉在每页重复:页眉是系统按 HIS 数据渲染的,服务端生成 PDF 时同样要按页重复;
|
||||
* ③ 页码只写 "1 / 2" 这类 ASCII:jsPDF 内置字体不含中文,
|
||||
* 画中文页码需要内嵌字体(体积会明显变大),这一步留给服务端用真字体实现。
|
||||
* 画中文页码需要内嵌字体(体积会明显变大),这一步留给服务端用真字体实现;
|
||||
* ④ 导出前对 flex 容器做一次兼容降级:html2canvas 不实现 flex 布局,
|
||||
* 填写项胶囊里的文字、输入框取值、签名图会被整块丢掉,见 applyExportFlexFallback。
|
||||
*
|
||||
* 输出为位图 PDF:文本不可选中,仅供原型演示;正式文书以服务端生成的 PDF 为准。
|
||||
*/
|
||||
@@ -36,6 +38,44 @@ export interface SigningPdfInput {
|
||||
fileName: string
|
||||
}
|
||||
|
||||
/**
|
||||
* html2canvas 兼容处理:flex 容器里的文字与控件取值会被整块丢掉。
|
||||
*
|
||||
* 实测(签署工作台导出的 PDF,html2canvas 1.4):页面上明明印着「与患者关系:文本框 配偶」、
|
||||
* 签名图也画出来了,导出的位图里这些却全是空白,只剩胶囊的边框和底色——
|
||||
* 填写项胶囊 `.sign-field` 与控件容器 `.sign-field__control` 都是 `display: inline-flex`,
|
||||
* 而 html2canvas 1.4 不实现 flex 布局,容器内文本的落点算不出来,
|
||||
* 于是连同 `<input>` 的取值、签名 `<img>` 一起被丢掉(连 `<p>` 里的「待签名」提示也不见了)。
|
||||
*
|
||||
* 换成 `inline-block` 后内容全部回来,于是这里把这两层降级。**只在导出克隆体上改**:
|
||||
* 屏幕上的版式一行不动,PDF 也不会丢内容;`.sign-doc-header` 那层 flex 实测不受影响,不动它。
|
||||
*
|
||||
* gap 在 inline-block 下失效,所以把原来的 4px 项间距、align-items: center、
|
||||
* 签名位的 justify-content: center 用等效的 inline 写法补回来,导出结果与屏幕观感一致。
|
||||
*/
|
||||
function applyExportFlexFallback(root: HTMLElement) {
|
||||
root.querySelectorAll<HTMLElement>('.sign-field, .sign-field__control').forEach((element) => {
|
||||
element.style.display = 'inline-block'
|
||||
})
|
||||
|
||||
// 胶囊原来是 inline-flex + gap: 4px,项名与控件之间的间距要自己补
|
||||
root.querySelectorAll<HTMLElement>('.sign-field__label').forEach((element) => {
|
||||
element.style.marginRight = '4px'
|
||||
})
|
||||
|
||||
root.querySelectorAll<HTMLElement>('.sign-field__control').forEach((element) => {
|
||||
// 原来是 align-items: center
|
||||
element.style.verticalAlign = 'middle'
|
||||
})
|
||||
|
||||
// 签名位原来是 justify-content: center,inline-block 下改用 text-align 居中
|
||||
root
|
||||
.querySelectorAll<HTMLElement>('.sign-field--signature .sign-field__control')
|
||||
.forEach((element) => {
|
||||
element.style.textAlign = 'center'
|
||||
})
|
||||
}
|
||||
|
||||
/** 量固定页眉的高度(含下外边距)——它是每页要重复的那一条 */
|
||||
function measureHeaderHeight(element: HTMLElement) {
|
||||
const header = element.querySelector<HTMLElement>('.sign-doc-header')
|
||||
@@ -68,6 +108,8 @@ export async function createSigningPdf(input: SigningPdfInput): Promise<Blob> {
|
||||
useCORS: true,
|
||||
logging: false,
|
||||
onclone: (clonedDocument, clonedElement) => {
|
||||
applyExportFlexFallback(clonedElement)
|
||||
|
||||
clonedElement.style.width = `${CAPTURE_WIDTH_PX}px`
|
||||
clonedElement.style.height = 'auto'
|
||||
clonedElement.style.maxHeight = 'none'
|
||||
|
||||
Reference in New Issue
Block a user