word 预览优化

This commit is contained in:
cwchen 2025-11-12 10:26:29 +08:00
parent f05818d31a
commit ee0581326a
1 changed files with 113 additions and 17 deletions

View File

@ -49,8 +49,6 @@
<script> <script>
import * as docxPreview from 'docx-preview/dist/docx-preview.js' import * as docxPreview from 'docx-preview/dist/docx-preview.js'
const DOCX_CUSTOM_STYLE_ID = 'docx-preview-custom-style'
const DEFAULT_DOC_URL = 'http://192.168.0.14:9090/smart-bid/technicalSolutionDatabase/2025/11/11/887b35d28b2149b6a7555fb639be9411.docx' const DEFAULT_DOC_URL = 'http://192.168.0.14:9090/smart-bid/technicalSolutionDatabase/2025/11/11/887b35d28b2149b6a7555fb639be9411.docx'
export default { export default {
@ -365,21 +363,117 @@ export default {
wrapContentWithArticle(container) { wrapContentWithArticle(container) {
if (!container) return if (!container) return
const existingArticle = container.querySelector(':scope > article.docx-article-wrapper') const sections = Array.from(container.querySelectorAll('.docx-wrapper section'))
if (existingArticle) { if (sections.length === 0) {
this.wrapElementsInSections(container)
return return
} }
const article = document.createElement('article') sections.forEach((section) => {
article.className = 'docx-article-wrapper' this.wrapElementsInSections(section)
const nodes = Array.from(container.childNodes) })
.filter((node) => node.nodeType === Node.ELEMENT_NODE || (node.nodeType === Node.TEXT_NODE && node.textContent.trim())) },
nodes.forEach((node) => {
if (node !== article) { wrapElementsInSections(node) {
article.appendChild(node) if (!node) return
// header footer
const selectors = [
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
'ul', 'ol', 'blockquote', 'table'
]
console.log(node);
//
const allElements = Array.from(node.querySelectorAll(selectors.join(',')))
//
const elements = allElements.filter(el => {
// header footer
let parent = el.parentElement
while (parent && parent !== node) {
const tag = parent.tagName ? parent.tagName.toLowerCase() : ''
if (tag === 'header' || tag === 'footer') {
return false // header/footer
}
//
if (selectors.includes(tag)) {
return false
}
parent = parent.parentElement
}
return true
})
if (elements.length === 0) return
//
const elementGroups = this.groupConsecutiveElements(elements)
// article
elementGroups.forEach(group => {
if (group.length > 0) {
this.wrapElementGroupWithArticle(group)
} }
}) })
container.appendChild(article)
}, },
groupConsecutiveElements(elements) {
const groups = []
let currentGroup = []
elements.forEach((el, index) => {
//
if (currentGroup.length === 0) {
currentGroup.push(el)
return
}
// DOM
const lastEl = currentGroup[currentGroup.length - 1]
let nextElement = lastEl.nextElementSibling
//
while (nextElement && nextElement.nodeType !== 1) {
nextElement = nextElement.nextElementSibling
}
if (nextElement === el) {
//
currentGroup.push(el)
} else {
//
groups.push([...currentGroup])
currentGroup = [el]
}
//
if (index === elements.length - 1) {
groups.push([...currentGroup])
}
})
return groups
},
wrapElementGroupWithArticle(elements) {
if (!elements || elements.length === 0) return
const firstElement = elements[0]
const parent = firstElement.parentElement
// article
const article = document.createElement('article')
article.className = 'docx-article-wrapper'
// article
parent.insertBefore(article, firstElement)
// article
elements.forEach(el => {
article.appendChild(el)
})
}
}, },
} }
</script> </script>
@ -395,12 +489,16 @@ export default {
} }
.document-search-word article.docx-article-wrapper { .document-search-word article.docx-article-wrapper {
max-width: 960px; display: block;
margin: 0 auto; margin: 0 auto 32px;
background: #ffffff; background: #ffffff;
border-radius: 16px; border-radius: 16px;
box-shadow: 0 18px 40px rgba(25, 64, 158, 0.12); box-shadow: 0 20px 48px rgba(25, 64, 158, 0.12);
padding: 48px 56px; padding: 48px 56px;
box-sizing: border-box;
color: #1f2a62;
line-height: 1.75;
font-size: 14px;
} }
.search-toolbar { .search-toolbar {
@ -702,6 +800,4 @@ export default {
background: #206dff !important; background: #206dff !important;
color: #ffffff; color: #ffffff;
} }
</style> </style>