使用表格来实现垂直居中

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-order.xml',
'tooltip.xml',
'w.xml'
'w.xml',
'jianli.docx',
'text-background.docx'
],
docx4j: [
'ArialUnicodeMS.docx',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -94,16 +94,16 @@ export function renderDrawing(
container.style.height = ext.cy;
if (spPr.geom) {
const width = parseFloat(ext.cx.replace('pt', ''));
const height = parseFloat(ext.cy.replace('pt', ''));
const width = parseFloat(ext.cx.replace('px', ''));
const height = parseFloat(ext.cy.replace('px', ''));
appendChild(
container,
renderGeom(spPr.geom, spPr, width, height, wps.wpsStyle)
);
}
if (spPr.custGeom) {
const width = parseFloat(ext.cx.replace('pt', ''));
const height = parseFloat(ext.cy.replace('pt', ''));
const width = parseFloat(ext.cx.replace('px', ''));
const height = parseFloat(ext.cy.replace('px', ''));
appendChild(
container,
renderCustGeom(spPr.custGeom, spPr, width, height, wps.wpsStyle)
@ -117,16 +117,28 @@ export function renderDrawing(
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) {
if (txbxContentChild instanceof Paragraph) {
const cssStyle = txbxContentChild.properties.cssStyle;
// 其实不太准,但一般情况下只有一个段落吧
if (cssStyle && cssStyle['text-align']) {
container.style.justifyContent = String(cssStyle['text-align']);
}
appendChild(container, renderParagraph(word, txbxContentChild));
appendChild(textContainer, renderParagraph(word, txbxContentChild));
} 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.pageMarginBottom) {
sectionEl.style.marginBottom = renderOptions.pageMarginBottom + 'pt';
sectionEl.style.marginBottom = renderOptions.pageMarginBottom + 'px';
}
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) {