使用表格来实现垂直居中

This commit is contained in:
wuduoyi 2023-04-18 17:28:41 +08:00
parent 84e2c39f09
commit 2e90026870
10 changed files with 59 additions and 40 deletions

View File

@ -41,7 +41,9 @@ const fileLists = {
'textbox-rotation.xml', 'textbox-rotation.xml',
'textbox-order.xml', 'textbox-order.xml',
'tooltip.xml', 'tooltip.xml',
'w.xml' 'w.xml',
'jianli.docx',
'text-background.docx'
], ],
docx4j: [ docx4j: [
'ArialUnicodeMS.docx', 'ArialUnicodeMS.docx',

View File

@ -28,8 +28,8 @@ export function shapeToSVG(
'style', 'style',
'overflow: visible; position: absolute; z-index: -1' 'overflow: visible; position: absolute; z-index: -1'
); );
svg.setAttribute('width', width.toString() + 'pt'); svg.setAttribute('width', width.toString() + 'px');
svg.setAttribute('height', height.toString() + 'pt'); svg.setAttribute('height', height.toString() + 'px');
// 变量值 // 变量值
const vars: Var = presetVal(width, height); const vars: Var = presetVal(width, height);

View File

@ -56,13 +56,13 @@ function parseBodyPr(element: Element, style: CSSStyle) {
const anchor = value as ST_TextAnchoringType; const anchor = value as ST_TextAnchoringType;
switch (anchor) { switch (anchor) {
case 'b': case 'b':
style['align-items'] = 'flex-end'; style['vertical-align'] = 'bottom';
break; break;
case 't': case 't':
style['align-items'] = 'flex-start'; style['vertical-align'] = 'top';
break; break;
case 'ctr': case 'ctr':
style['align-items'] = 'center'; style['vertical-align'] = 'middle';
break; break;
} }
break; break;

View File

@ -2,16 +2,21 @@
* docxjs * docxjs
*/ */
export type LengthType = 'pt' | '%' | ''; export type LengthType = 'px' | 'pt' | '%' | '';
export type LengthUsageType = {mul: number; unit: LengthType}; export type LengthUsageType = {mul: number; unit: LengthType};
/**
* px svg
*/
const ptToPx = 1.3333;
export const LengthUsage: Record<string, LengthUsageType> = { export const LengthUsage: Record<string, LengthUsageType> = {
Dxa: {mul: 0.05, unit: 'pt'}, //twips Dxa: {mul: ptToPx * 0.05, unit: 'px'}, //twips
Emu: {mul: 1 / 12700, unit: 'pt'}, Emu: {mul: (ptToPx * 1) / 12700, unit: 'px'},
FontSize: {mul: 0.5, unit: 'pt'}, FontSize: {mul: ptToPx * 0.5, unit: 'px'},
Border: {mul: 0.125, unit: 'pt'}, Border: {mul: ptToPx * 0.125, unit: 'px'},
Point: {mul: 1, unit: 'pt'}, Point: {mul: ptToPx * 1, unit: 'px'},
Percent: {mul: 0.02, unit: '%'}, Percent: {mul: 0.02, unit: '%'},
LineHeight: {mul: 1 / 240, unit: ''}, LineHeight: {mul: 1 / 240, unit: ''},
VmlEmu: {mul: 1 / 12700, unit: ''} VmlEmu: {mul: 1 / 12700, unit: ''}

View File

@ -37,25 +37,25 @@ export function fixAbsolutePosition(
const leftStyle = style.left; const leftStyle = style.left;
if (leftStyle) { if (leftStyle) {
style.left = `${ style.left = `${
parseInt(String(leftStyle).replace('pt', ''), 10) + paddingLeft parseInt(String(leftStyle).replace('px', ''), 10) + paddingLeft
}pt`; }px`;
} }
const topStyle = style.top; const topStyle = style.top;
if (topStyle) { if (topStyle) {
style.top = `${ style.top = `${
parseInt(String(topStyle).replace('pt', ''), 10) + paddingTop parseInt(String(topStyle).replace('px', ''), 10) + paddingTop
}pt`; }px`;
} }
const rightStyle = style.right; const rightStyle = style.right;
if (rightStyle) { if (rightStyle) {
style.right = `${ style.right = `${
parseInt(String(rightStyle).replace('pt', ''), 10) + paddingRight parseInt(String(rightStyle).replace('px', ''), 10) + paddingRight
}pt`; }px`;
} }
const bottomStyle = style.bottom; const bottomStyle = style.bottom;
if (bottomStyle) { if (bottomStyle) {
style.bottom = `${ style.bottom = `${
parseInt(String(bottomStyle).replace('pt', ''), 10) + paddingBottom parseInt(String(bottomStyle).replace('px', ''), 10) + paddingBottom
}pt`; }px`;
} }
} }

View File

@ -77,11 +77,11 @@ function getSectionEnd(section: Section, sectionEl: HTMLElement): SectionEnd {
const pageMargin = section.properties.pageMargin; const pageMargin = section.properties.pageMargin;
let bottom = sectionBound.top + sectionBound.height; let bottom = sectionBound.top + sectionBound.height;
if (pageMargin?.bottom) { if (pageMargin?.bottom) {
bottom = bottom - parseInt(pageMargin.bottom.replace('pt', ''), 10); bottom = bottom - parseInt(pageMargin.bottom.replace('px', ''), 10);
} }
let right = sectionBound.left + sectionBound.width; let right = sectionBound.left + sectionBound.width;
if (pageMargin?.right) { if (pageMargin?.right) {
right = right - parseInt(pageMargin.right.replace('pt', ''), 10); right = right - parseInt(pageMargin.right.replace('px', ''), 10);
} }
return {bottom, right}; return {bottom, right};
} }
@ -99,15 +99,15 @@ function getTransform(
if (renderOptions.zoomFitWidth && !renderOptions.ignoreWidth) { if (renderOptions.zoomFitWidth && !renderOptions.ignoreWidth) {
const pageWidth = pageSize?.width; const pageWidth = pageSize?.width;
if (rootWidth && pageWidth) { if (rootWidth && pageWidth) {
let pageWidthNum = parseInt(pageWidth.replace('pt', ''), 10); let pageWidthNum = parseInt(pageWidth.replace('px', ''), 10);
if (props.pageMargin) { if (props.pageMargin) {
const pageMargin = props.pageMargin; const pageMargin = props.pageMargin;
pageWidthNum += pageMargin.left pageWidthNum += pageMargin.left
? parseInt(pageMargin.left.replace('pt', ''), 10) ? parseInt(pageMargin.left.replace('px', ''), 10)
: 0; : 0;
pageWidthNum += pageMargin.right pageWidthNum += pageMargin.right
? parseInt(pageMargin.right.replace('pt', ''), 10) ? parseInt(pageMargin.right.replace('px', ''), 10)
: 0; : 0;
} }
const zoomWidth = rootWidth / pageWidthNum; const zoomWidth = rootWidth / pageWidthNum;

View File

@ -94,16 +94,16 @@ export function renderDrawing(
container.style.height = ext.cy; container.style.height = ext.cy;
if (spPr.geom) { if (spPr.geom) {
const width = parseFloat(ext.cx.replace('pt', '')); const width = parseFloat(ext.cx.replace('px', ''));
const height = parseFloat(ext.cy.replace('pt', '')); const height = parseFloat(ext.cy.replace('px', ''));
appendChild( appendChild(
container, container,
renderGeom(spPr.geom, spPr, width, height, wps.wpsStyle) renderGeom(spPr.geom, spPr, width, height, wps.wpsStyle)
); );
} }
if (spPr.custGeom) { if (spPr.custGeom) {
const width = parseFloat(ext.cx.replace('pt', '')); const width = parseFloat(ext.cx.replace('px', ''));
const height = parseFloat(ext.cy.replace('pt', '')); const height = parseFloat(ext.cy.replace('px', ''));
appendChild( appendChild(
container, container,
renderCustGeom(spPr.custGeom, spPr, width, height, wps.wpsStyle) renderCustGeom(spPr.custGeom, spPr, width, height, wps.wpsStyle)
@ -117,16 +117,28 @@ export function renderDrawing(
const txbxContent = wps.txbxContent; const txbxContent = wps.txbxContent;
if (txbxContent.length) {
// 为了实现垂直居中,将父容器改成 table 布局
const textContainer = document.createElement('div');
textContainer.dataset.name = 'textContainer';
container.style.display = 'table';
textContainer.style.display = 'table-cell';
textContainer.style.verticalAlign = 'middle';
if (wps.style && wps.style['vertical-align']) {
textContainer.style.verticalAlign = wps.style[
'vertical-align'
] as string;
// 容器的 vertical-align 需要去掉,虽然也不影响
container.style.verticalAlign = '';
}
appendChild(container, textContainer);
for (const txbxContentChild of txbxContent) { for (const txbxContentChild of txbxContent) {
if (txbxContentChild instanceof Paragraph) { if (txbxContentChild instanceof Paragraph) {
const cssStyle = txbxContentChild.properties.cssStyle; appendChild(textContainer, renderParagraph(word, txbxContentChild));
// 其实不太准,但一般情况下只有一个段落吧
if (cssStyle && cssStyle['text-align']) {
container.style.justifyContent = String(cssStyle['text-align']);
}
appendChild(container, renderParagraph(word, txbxContentChild));
} else if (txbxContentChild instanceof Table) { } else if (txbxContentChild instanceof Table) {
appendChild(container, renderTable(word, txbxContentChild)); appendChild(textContainer, renderTable(word, txbxContentChild));
}
} }
} }
} }

View File

@ -19,11 +19,11 @@ export function renderSection(
if (renderOptions.page) { if (renderOptions.page) {
if (renderOptions.pageMarginBottom) { if (renderOptions.pageMarginBottom) {
sectionEl.style.marginBottom = renderOptions.pageMarginBottom + 'pt'; sectionEl.style.marginBottom = renderOptions.pageMarginBottom + 'px';
} }
if (renderOptions.pageShadow) { if (renderOptions.pageShadow) {
sectionEl.style.boxShadow = '0 0 8pt rgba(0, 0, 0, 0.5)'; sectionEl.style.boxShadow = '0 0 8px rgba(0, 0, 0, 0.5)';
} }
if (renderOptions.pageBackground) { if (renderOptions.pageBackground) {