diff --git a/package.json b/package.json
index 28bd629..b04e3df 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"core-js": "3.6.5",
"docx": "^9.4.1",
"docx-parser": "^0.2.1",
+ "docx-preview": "^0.1.14",
"docx2html": "^1.3.2",
"docxtemplater": "^3.61.1",
"echarts": "^5.6.0",
diff --git a/src/views/businessConfig/EditPayForm.vue b/src/views/businessConfig/EditPayForm.vue
index ee21003..f082ebe 100644
--- a/src/views/businessConfig/EditPayForm.vue
+++ b/src/views/businessConfig/EditPayForm.vue
@@ -26,15 +26,7 @@
@@ -159,15 +151,7 @@
>
@@ -189,7 +173,7 @@ export default {
previewContent: '', // 预览内容
showEditDrawer: false,
showPreviewModal: false, // 添加预览模态窗口控制变量
- currentTemplateIndex: 1,
+ currentTemplateIndex: 0,
editForm: {
field: '', // Renamed from name to field
name: '', // Renamed from label to name (Chinese name)
@@ -201,6 +185,10 @@ export default {
docxUrl: null,
templateFile: null,
templates: [
+ {
+ name:'',
+ content:''
+ },
{
name: '资金划拨审批单',
content: `
@@ -866,15 +854,21 @@ export default {
this.loadTemplate(newVal);
}
},
- formatType: {
- immediate: true,
- handler(val) {
- if (val === 1) {
- this.loadTemplate(this.currentTemplateIndex);
- } else {
- this.codeContent = '\n\n \n'
- this.previewContent = ''
+ formatType(newVal) {
+ if (newVal === 1) {
+ // HTML 格式
+ if (this.$refs.codeEditor) {
+ this.$refs.codeEditor.setValue(this.codeContent)
}
+ this.previewContent = this.codeContent
+ this.handleRefresh()
+ } else if (newVal === 2) {
+ // DOCX 格式
+ if (this.$refs.codeEditor) {
+ this.$refs.codeEditor.setValue(this.codeContent)
+ }
+ this.previewContent = this.codeContent
+ this.handleRefresh()
}
}
},
@@ -916,68 +910,21 @@ export default {
this.previewContent = processedContent;
},
handleUpload() {
- // 创建文件输入元素
- const input = document.createElement('input');
- input.type = 'file';
- input.accept = '.docx';
-
- // 监听文件选择事件
+ const input = document.createElement('input')
+ input.type = 'file'
+ input.accept = '.docx'
input.onchange = async (e) => {
- const file = e.target.files[0];
+ e.preventDefault() // 阻止默认行为
+ const file = e.target.files[0]
if (file) {
- // 检查文件类型
if (!file.name.endsWith('.docx')) {
- this.$message.error('请选择docx格式的文件');
- return;
- }
-
- try {
- // 创建临时URL
- const blobUrl = URL.createObjectURL(file);
- // 使用 Microsoft Office Online Viewer
- this.docxUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(blobUrl)}`;
-
- // 清空代码预览区
- this.codeContent = '';
-
- // 将文件转换为ArrayBuffer
- const arrayBuffer = await this.readFileAsArrayBuffer(file);
-
- // 使用mammoth转换docx为HTML,用于提取变量
- const result = await mammoth.convertToHtml({
- arrayBuffer,
- transformDocument: (document) => {
- return document;
- }
- });
-
- // 提取占位变量
- const variables = this.extractVariables(result.value);
-
- // 显示提取的HTML内容
- this.codeContent = result.value;
-
- // 更新字段元数据
- this.updateFieldMetadata(variables);
-
- } catch (error) {
- console.error('处理文档失败:', error);
- this.$message.error('处理文档失败,请重试');
+ this.$message.error('请选择docx格式的文件')
+ return
}
+ await this.convertDocxToHtml(file)
}
- };
-
- // 触发文件选择对话框
- input.click();
- },
-
- readFileAsArrayBuffer(file) {
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onload = (event) => resolve(event.target.result);
- reader.onerror = (error) => reject(error);
- reader.readAsArrayBuffer(file);
- });
+ }
+ input.click()
},
handleEditField(field) {
this.editForm = { ...field };
@@ -1189,7 +1136,132 @@ export default {
extractAndUpdateFields() {
const variables = this.extractVariables(this.codeContent) // variables are field names
this.updateFieldMetadata(variables) // Pass field names
- }
+ },
+ async convertDocxToHtml(file) {
+ try {
+ // 设置表格名称为文件名(去掉扩展名)
+ const fileName = file.name.replace(/\.[^/.]+$/, "")
+ this.formName = fileName
+
+ const reader = new FileReader()
+ const arrayBuffer = await new Promise((resolve, reject) => {
+ reader.onload = (e) => resolve(e.target.result)
+ reader.onerror = (e) => reject(e)
+ reader.readAsArrayBuffer(file)
+ })
+
+ const result = await mammoth.convertToHtml({
+ arrayBuffer,
+ convertImage: mammoth.images.imgElement(function(image) {
+ return image.read("base64").then(function(imageBuffer) {
+ return {
+ src: "data:" + image.contentType + ";base64," + imageBuffer
+ };
+ });
+ }),
+ styleMap: [
+ "p[style-name='Normal'] => p:style='margin: 0; padding: 0;'",
+ "p[style-name='Heading 1'] => h1:style='font-size: 24px; font-weight: bold; margin: 0 0 20px 0;'",
+ "p[style-name='Heading 2'] => h2:style='font-size: 20px; font-weight: bold; margin: 0 0 16px 0;'",
+ "p[style-name='Heading 3'] => h3:style='font-size: 18px; font-weight: bold; margin: 0 0 14px 0;'",
+ "p[style-name='Heading 4'] => h4:style='font-size: 16px; font-weight: bold; margin: 0 0 12px 0;'",
+ "p[style-name='Heading 5'] => h5:style='font-size: 14px; font-weight: bold; margin: 0 0 10px 0;'",
+ "p[style-name='Heading 6'] => h6:style='font-size: 12px; font-weight: bold; margin: 0 0 8px 0;'",
+ "p[style-name='List Paragraph'] => p:style='margin: 0; padding: 0; list-style-type: disc;'",
+ "p[style-name='Quote'] => blockquote:style='margin: 0 0 16px 0; padding: 10px 20px; border-left: 4px solid #ccc;'",
+ "p[style-name='Intense Quote'] => blockquote:style='margin: 0 0 16px 0; padding: 10px 20px; border-left: 4px solid #666; background: #f5f5f5;'",
+ "r[style-name='Strong'] => strong:style='font-weight: bold;'",
+ "r[style-name='Emphasis'] => em:style='font-style: italic;'",
+ "r[style-name='Code'] => code:style='font-family: monospace; background: #f5f5f5; padding: 2px 4px;'",
+ "table => table:style='width: 100%; border-collapse: collapse; margin: 0 0 16px 0;'",
+ "tr => tr:style='border-bottom: 1px solid #ddd;'",
+ "td => td:style='padding: 8px; border: 1px solid #ddd; text-align: center; vertical-align: middle;'",
+ "th => th:style='padding: 8px; border: 1px solid #ddd; font-weight: bold; text-align: center; vertical-align: middle;'",
+ "table[style-name='Table Grid'] => table:style='width: 100%; border-collapse: collapse; margin: 0 0 16px 0; border: 1px solid #000;'",
+ "table[style-name='Table Grid Light'] => table:style='width: 100%; border-collapse: collapse; margin: 0 0 16px 0; border: 1px solid #ddd;'",
+ "table[style-name='Table Grid Dark'] => table:style='width: 100%; border-collapse: collapse; margin: 0 0 16px 0; border: 1px solid #000;'",
+ "table[style-name='Table Grid Medium'] => table:style='width: 100%; border-collapse: collapse; margin: 0 0 16px 0; border: 1px solid #666;'"
+ ],
+ transformDocument: function(document) {
+ return document;
+ }
+ })
+
+ // 处理转换后的 HTML,确保所有样式都内嵌
+ let html = result.value
+
+ // 处理表格样式,保留原始边框样式
+ html = html.replace(/ {
+ if (match.includes('style-name="Table Grid"')) {
+ return ' {
+ let style = 'padding: 8px; border: 1px solid #ddd; text-align: center; vertical-align: middle;'
+ if (match.includes('style-name="Table Grid"')) {
+ style = 'padding: 8px; border: 1px solid #000; text-align: center; vertical-align: middle;'
+ } else if (match.includes('style-name="Table Grid Light"')) {
+ style = 'padding: 8px; border: 1px solid #ddd; text-align: center; vertical-align: middle;'
+ } else if (match.includes('style-name="Table Grid Dark"')) {
+ style = 'padding: 8px; border: 1px solid #000; text-align: center; vertical-align: middle;'
+ } else if (match.includes('style-name="Table Grid Medium"')) {
+ style = 'padding: 8px; border: 1px solid #666; text-align: center; vertical-align: middle;'
+ }
+ return `| {
+ let style = 'padding: 8px; border: 1px solid #ddd; font-weight: bold; text-align: center; vertical-align: middle;'
+ if (match.includes('style-name="Table Grid"')) {
+ style = 'padding: 8px; border: 1px solid #000; font-weight: bold; text-align: center; vertical-align: middle;'
+ } else if (match.includes('style-name="Table Grid Light"')) {
+ style = 'padding: 8px; border: 1px solid #ddd; font-weight: bold; text-align: center; vertical-align: middle;'
+ } else if (match.includes('style-name="Table Grid Dark"')) {
+ style = 'padding: 8px; border: 1px solid #000; font-weight: bold; text-align: center; vertical-align: middle;'
+ } else if (match.includes('style-name="Table Grid Medium"')) {
+ style = 'padding: 8px; border: 1px solid #666; font-weight: bold; text-align: center; vertical-align: middle;'
+ }
+ return ` | /g, ' ')
+
+ // 处理图片样式
+ html = html.replace(/ {
+ // 更新代码编辑器内容
+ if (this.$refs.codeEditor) {
+ this.$refs.codeEditor.setValue(html)
+ }
+ // 更新预览内容
+ this.previewContent = html
+ this.handleRefresh()
+ })
+ } catch (error) {
+ console.error('转换失败:', error)
+ this.$message.error('文件转换失败')
+ }
+ },
},
// 在组件销毁时释放URL
beforeDestroy() {
|