vue-将组件内容导出为Word文档-docx
1. 安装依赖
首先,我们需要安装docx库,以便在前端生成Word文档。可以通过以下命令进行安装:
npm install docx
2. 实现导出功能
2.1 初始化文档
使用docx库创建一个新的文档实例,并定义文档的结构和内容。我们使用Document、Paragraph和TextRun等类来构建文档。
const doc = new Document({
sections: [{
properties: {},
children: [
new Paragraph({
children: [new TextRun({ text: `id:${proposalDetail.value.pid}【这里填写自己要的信息哈】`, size: 24 })],
spacing: { after: 200 },
alignment: 'right', // 右对齐
}),
new Paragraph({
children: [
new TextRun({
text: "详情信息",
bold: true,
size: 32,
}),
],
spacing: { after: 400 },
}),
// 其他信息...
],
}],
});
每个信息都使用Paragraph和TextRun进行格式化。总之就是要添加什么,就new 一个 Paragraph或者是TextPath(看代码就知道啥意思了)
2.2 生成并下载文档
使用Packer.toBlob方法将文档转换为Blob对象,并使用file-saver库的saveAs方法下载文档。
const blob = await Packer.toBlob(doc);
saveAs(blob, `${proposalDetail.value.pid || '详情'}.docx`);
2.3完整代码(以我的实现为例)
// 下载提案内容为Word文档
const download = async () => {
try {
isDownloading.value = true
// 创建文档
const doc = new Document({
sections: [{
properties: {},
children: [
new Paragraph({
children: [new TextRun({ text: `提案号:${proposalDetail.value.pid}`, size: 24 })],
spacing: { after: 200 },
alignment: 'right',
}),
new Paragraph({
children: [
new TextRun({
text: "提案详情",
bold: true,
size: 32,
}),
],
spacing: { after: 400 },
}),
// 基本信息
new Paragraph({
children: [new TextRun({ text: `案由:${proposalDetail.value.caseReason}`, size: 24 })],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: `提案人:${proposalDetail.value.proposer}`, size: 24 })],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: `联名人:${proposalDetail.value.signers || '无'}`, size: 24 })],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: `提案人地区:${proposalDetail.value.proposerRegion}`, size: 24 })],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: `提案类型:${proposalDetail.value.proposalType}`, size: 24 })],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: `提交时间:${formatDateTime(proposalDetail.value.submitTime)}`, size: 24 })],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: `是否愿意公示:${proposalDetail.value.isPublic ? '是' : '否'}`, size: 24 })],
spacing: { after: 400 },
}),
// 提案内容
new Paragraph({
children: [
new TextRun({
text: "提案内容:",
bold: true,
size: 24,
}),
],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: proposalDetail.value.proposalContent, size: 24 })],
spacing: { after: 400 },
}),
// 处理结果
new Paragraph({
children: [
new TextRun({
text: "处理结果:",
bold: true,
size: 24,
}),
],
spacing: { after: 200 },
}),
new Paragraph({
children: [new TextRun({ text: proposalDetail.value.handingResult || '暂无处理结果', size: 24 })],
spacing: { after: 400 },
}),
// 添加处理状态部分
new Paragraph({
children: [
new TextRun({
text: "处理状态:",
bold: true,
size: 24,
}),
],
spacing: { after: 200 },
}),
// 添加所有状态阶段
...getStatusInfo.value
.filter(stage => !stage.isHidden)
.map(stage =>
new Paragraph({
children: [
new TextRun({
text: `${stage.label}—— `,
size: 24
}),
new TextRun({
text: getStatusText(stage),
size: 24,
color: stage.isRejected ? 'FF0000' : // 红色
stage.isProcessing ? '409EFF' : // 蓝色
!stage.time ? '909399' : '333333' // 灰色或黑色
})
],
spacing: { after: 200 },
})
)
],
}],
})
// 生成文档
const blob = await Packer.toBlob(doc)
saveAs(blob, `提案${proposalDetail.value.pid || '详情'}.docx`)
ElMessage.success('提案内容已保存为Word文档')
} catch (error) {
console.error('生成Word文档失败:', error)
ElMessage.error('生成Word文档失败,请重试')
} finally {
isDownloading.value = false
}
}
3. 用户界面
在用户界面中,我们使用Element Plus的按钮组件来触发导出功能。按钮的文本会根据导出状态进行更新,提供良好的用户体验。
<el-button type="danger" @click="download" :loading="isDownloading" class="action-button">
{{ isDownloading ? '正在生成...' : '详情导出Word' }}
</el-button>