perf: 导出word 的目录索引
parent
13aa0b1ea0
commit
d9e9ffa362
@ -1,308 +0,0 @@
|
|||||||
import { isEmpty } from '@/utils/commons';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import {
|
|
||||||
AlignmentType,
|
|
||||||
BorderStyle,
|
|
||||||
Document,
|
|
||||||
Footer,
|
|
||||||
Header,
|
|
||||||
HeadingLevel,
|
|
||||||
LevelFormat,
|
|
||||||
NumberFormat,
|
|
||||||
PageNumber,
|
|
||||||
Paragraph,
|
|
||||||
Tab,
|
|
||||||
Table,
|
|
||||||
TableCell,
|
|
||||||
TableRow,
|
|
||||||
TabStopType,
|
|
||||||
TextRun,
|
|
||||||
WidthType,
|
|
||||||
Media,
|
|
||||||
} from 'docx';
|
|
||||||
// import { splitTable_6, splitTable_7, splitTable_B, splitTable_D, splitTable_J, splitTable_Q, splitTable_R, splitTable_8 } from '@/hooks/useProductsQuotationFormat';
|
|
||||||
// import { formatGroupSize } from '@/hooks/useProductsSets';
|
|
||||||
import logo from './cht letter header logo.png';
|
|
||||||
|
|
||||||
const unitMap = {
|
|
||||||
'0': '人',
|
|
||||||
'1': '团',
|
|
||||||
};
|
|
||||||
|
|
||||||
const DOC_TITLE = '地接合同';
|
|
||||||
const pageMargins = {
|
|
||||||
top: `15mm`,
|
|
||||||
bottom: `15mm`,
|
|
||||||
left: `10mm`,
|
|
||||||
right: `10mm`,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tableBorderNone = {
|
|
||||||
top: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
|
|
||||||
bottom: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
|
|
||||||
left: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
|
|
||||||
right: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
|
|
||||||
};
|
|
||||||
const tableBorderOne = {
|
|
||||||
top: { style: BorderStyle.SINGLE, space: 0, size: 6, color: 'auto' },
|
|
||||||
bottom: { style: BorderStyle.SINGLE, space: 0, size: 6, color: 'auto' },
|
|
||||||
left: { style: BorderStyle.SINGLE, space: 0, size: 6, color: 'auto' },
|
|
||||||
right: { style: BorderStyle.SINGLE, space: 0, size: 6, color: 'auto' },
|
|
||||||
};
|
|
||||||
const tableBorderInner = {
|
|
||||||
top: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
bottom: { style: BorderStyle.INSET, space: 0, size: 6, color: 'auto' },
|
|
||||||
left: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
right: { style: BorderStyle.INSET, space: 0, size: 6, color: 'auto' },
|
|
||||||
};
|
|
||||||
const tableBorderInnerB = {
|
|
||||||
top: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
bottom: { style: BorderStyle.INSET, space: 0, size: 6, color: 'auto' },
|
|
||||||
left: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
right: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
};
|
|
||||||
const tableBorderInnerDashB = {
|
|
||||||
top: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
bottom: { style: BorderStyle.DASHED, space: 0, size: 6, color: 'auto' },
|
|
||||||
left: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
right: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
};
|
|
||||||
const tableBorderInnerT = {
|
|
||||||
top: { style: BorderStyle.INSET, space: 0, size: 6, color: 'auto' },
|
|
||||||
bottom: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
left: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
right: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
};
|
|
||||||
const tableBorderInnerR = {
|
|
||||||
top: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
bottom: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
left: { style: BorderStyle.NONE, space: 0, size: 6, color: 'auto' },
|
|
||||||
right: { style: BorderStyle.INSET, space: 0, size: 6, color: 'auto' },
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @version
|
|
||||||
* @date 2025-08-20
|
|
||||||
*/
|
|
||||||
export default class TemplateLetter2025 {
|
|
||||||
#remarkList = {};
|
|
||||||
create([headerParams, activeAgency, agencyProducts, agencyExtras, remarks]) {
|
|
||||||
this.#remarkList = remarks;
|
|
||||||
const { use_year } = headerParams;
|
|
||||||
const h1 = `${activeAgency.travel_agency_name}${use_year}年${DOC_TITLE}`;
|
|
||||||
const yearStart = dayjs(`${use_year}-01-01`).format('YYYY.MM.DD');
|
|
||||||
const yearEnd = dayjs(`${use_year}-12-31`).format('YYYY.MM.DD');
|
|
||||||
|
|
||||||
const document = new Document({
|
|
||||||
creator: 'China Highlights',
|
|
||||||
title: h1,
|
|
||||||
subject: 'CH信笺2025',
|
|
||||||
styles: {
|
|
||||||
paragraphStyles: [
|
|
||||||
{
|
|
||||||
id: 'Normal',
|
|
||||||
name: 'Normal',
|
|
||||||
quickFormat: true,
|
|
||||||
run: {
|
|
||||||
size: 22,
|
|
||||||
font: { name: '宋体' },
|
|
||||||
color: '000000',
|
|
||||||
},
|
|
||||||
paragraph: {
|
|
||||||
spacing: {
|
|
||||||
after: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Title',
|
|
||||||
name: 'Title',
|
|
||||||
basedOn: 'Normal',
|
|
||||||
next: 'Normal',
|
|
||||||
quickFormat: true,
|
|
||||||
run: {
|
|
||||||
size: 44,
|
|
||||||
font: { name: '宋体' },
|
|
||||||
color: '000000',
|
|
||||||
},
|
|
||||||
paragraph: {
|
|
||||||
spacing: {
|
|
||||||
before: 200,
|
|
||||||
after: 200,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Heading1',
|
|
||||||
name: 'Heading 1',
|
|
||||||
basedOn: 'Normal',
|
|
||||||
next: 'Normal',
|
|
||||||
quickFormat: true,
|
|
||||||
run: {
|
|
||||||
size: 32,
|
|
||||||
font: { name: '宋体' },
|
|
||||||
color: '000000',
|
|
||||||
},
|
|
||||||
paragraph: {
|
|
||||||
spacing: {
|
|
||||||
before: 200,
|
|
||||||
after: 200,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Heading2',
|
|
||||||
name: 'Heading 2',
|
|
||||||
basedOn: 'Normal',
|
|
||||||
next: 'Normal',
|
|
||||||
quickFormat: true,
|
|
||||||
run: {
|
|
||||||
size: 28,
|
|
||||||
font: { name: '宋体' },
|
|
||||||
color: '000000',
|
|
||||||
},
|
|
||||||
paragraph: {
|
|
||||||
spacing: {
|
|
||||||
before: 120,
|
|
||||||
after: 120,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'TableHeader',
|
|
||||||
name: 'Table Header',
|
|
||||||
basedOn: 'Normal',
|
|
||||||
next: 'Normal',
|
|
||||||
quickFormat: true,
|
|
||||||
run: {
|
|
||||||
size: 22,
|
|
||||||
font: { name: '宋体' },
|
|
||||||
color: '000000',
|
|
||||||
bold: true,
|
|
||||||
},
|
|
||||||
paragraph: {
|
|
||||||
spacing: {
|
|
||||||
before: 80,
|
|
||||||
after: 80,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
numbering: {
|
|
||||||
config: [
|
|
||||||
{
|
|
||||||
reference: 'products-type',
|
|
||||||
levels: [{ level: 0, text: '%1、', format: LevelFormat.CHINESE_COUNTING }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: 'terms',
|
|
||||||
levels: [{ level: 0, text: '%1.', format: LevelFormat.DECIMAL }],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
properties: {
|
|
||||||
page: {
|
|
||||||
pageNumbers: {
|
|
||||||
start: 1,
|
|
||||||
formatType: NumberFormat.DECIMAL,
|
|
||||||
},
|
|
||||||
margin: pageMargins,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
default: new Header({
|
|
||||||
children: [
|
|
||||||
this.createPageHeaderRightText(`Tel: 86-773-2885311`, { italics: false }),
|
|
||||||
this.createPageHeaderRightText(`Fax: 86-773-2827424`, { italics: false }),
|
|
||||||
this.createPageHeaderRightText(`E-mail: products@chinahighlights.com`, { italics: false }),
|
|
||||||
this.createPageHeaderRightText(`Web site: https://www.chinahighlights.com`, { italics: false }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
footers: {
|
|
||||||
default: new Footer({
|
|
||||||
children: [
|
|
||||||
new Paragraph({
|
|
||||||
alignment: AlignmentType.CENTER,
|
|
||||||
children: [
|
|
||||||
new TextRun({
|
|
||||||
children: ['第', PageNumber.CURRENT, '页'],
|
|
||||||
size: 20,
|
|
||||||
}),
|
|
||||||
new TextRun({
|
|
||||||
children: [', 共 ', PageNumber.TOTAL_PAGES, '页'],
|
|
||||||
size: 20,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
new Paragraph({
|
|
||||||
alignment: AlignmentType.RIGHT,
|
|
||||||
children: [
|
|
||||||
new TextRun({
|
|
||||||
text: `${new Date().toLocaleString()}系统生成`,
|
|
||||||
italics: true,
|
|
||||||
size: 20,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
createHeading(text) {
|
|
||||||
return new Paragraph({
|
|
||||||
text: text,
|
|
||||||
heading: HeadingLevel.HEADING_1,
|
|
||||||
alignment: AlignmentType.CENTER,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createTitle(text) {
|
|
||||||
return new Paragraph({
|
|
||||||
text: text,
|
|
||||||
heading: HeadingLevel.TITLE,
|
|
||||||
alignment: AlignmentType.CENTER,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createSubHeading(text, style = {}) {
|
|
||||||
return new Paragraph({
|
|
||||||
text: text,
|
|
||||||
heading: HeadingLevel.HEADING_1,
|
|
||||||
...style,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async createPageHeaderLeftLogo(doc) {
|
|
||||||
const response = await fetch(logo);
|
|
||||||
const imageBuffer = await response.arrayBuffer();
|
|
||||||
return new Paragraph({
|
|
||||||
children: [
|
|
||||||
Media.addImage(doc, imageBuffer, 120, 60), // width, height
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
createPageHeaderRightText(text, style = {}) {
|
|
||||||
return new Paragraph({
|
|
||||||
alignment: AlignmentType.RIGHT,
|
|
||||||
children: [
|
|
||||||
new TextRun({
|
|
||||||
text: text,
|
|
||||||
italics: true,
|
|
||||||
size: 20,
|
|
||||||
...style,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue