@nguyenphp/antigravity-marketing 1.0.18 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -78
- package/package.json +4 -3
- package/templates/.agent/skills/marketing-report-expert/SKILL.md +70 -0
- package/templates/.agent/skills/minimax-docx/LICENSE +21 -0
- package/templates/.agent/skills/minimax-docx/SKILL.md +274 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/academic_styles.xml +250 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/corporate_styles.xml +284 -0
- package/templates/.agent/skills/minimax-docx/assets/styles/default_styles.xml +449 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/aesthetic-rules.xsd +470 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/business-rules.xsd +130 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/common-types.xsd +159 -0
- package/templates/.agent/skills/minimax-docx/assets/xsd/wml-subset.xsd +589 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_typography.md +357 -0
- package/templates/.agent/skills/minimax-docx/references/cjk_university_template_guide.md +184 -0
- package/templates/.agent/skills/minimax-docx/references/comments_guide.md +191 -0
- package/templates/.agent/skills/minimax-docx/references/design_good_bad_examples.md +829 -0
- package/templates/.agent/skills/minimax-docx/references/design_principles.md +819 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_element_order.md +308 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part1.md +4061 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part2.md +2820 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_encyclopedia_part3.md +3381 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_namespaces.md +82 -0
- package/templates/.agent/skills/minimax-docx/references/openxml_units.md +72 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_a_create.md +284 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_b_edit_content.md +295 -0
- package/templates/.agent/skills/minimax-docx/references/scenario_c_apply_template.md +456 -0
- package/templates/.agent/skills/minimax-docx/references/track_changes_guide.md +200 -0
- package/templates/.agent/skills/minimax-docx/references/troubleshooting.md +506 -0
- package/templates/.agent/skills/minimax-docx/references/typography_guide.md +294 -0
- package/templates/.agent/skills/minimax-docx/references/xsd_validation_guide.md +158 -0
- package/templates/.agent/skills/minimax-docx/scripts/doc_to_docx.sh +40 -0
- package/templates/.agent/skills/minimax-docx/scripts/docx_preview.sh +37 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
- package/templates/.agent/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
- package/templates/.agent/skills/minimax-docx/scripts/env_check.sh +196 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.ps1 +274 -0
- package/templates/.agent/skills/minimax-docx/scripts/setup.sh +504 -0
- package/templates/.agent/skills/minimax-multimodal-toolkit/SKILL.md +359 -0
- package/templates/.agent/skills/minimax-pdf/README.md +222 -0
- package/templates/.agent/skills/minimax-pdf/SKILL.md +201 -0
- package/templates/.agent/skills/minimax-pdf/design/design.md +381 -0
- package/templates/.agent/skills/minimax-pdf/scripts/cover.py +1579 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_inspect.py +200 -0
- package/templates/.agent/skills/minimax-pdf/scripts/fill_write.py +242 -0
- package/templates/.agent/skills/minimax-pdf/scripts/make.sh +491 -0
- package/templates/.agent/skills/minimax-pdf/scripts/merge.py +112 -0
- package/templates/.agent/skills/minimax-pdf/scripts/palette.py +559 -0
- package/templates/.agent/skills/minimax-pdf/scripts/reformat_parse.py +374 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_body.py +1055 -0
- package/templates/.agent/skills/minimax-pdf/scripts/render_cover.cjs +111 -0
- package/templates/.agent/skills/minimax-xlsx/SKILL.md +138 -0
- package/templates/.agent/skills/minimax-xlsx/references/create.md +691 -0
- package/templates/.agent/skills/minimax-xlsx/references/edit.md +684 -0
- package/templates/.agent/skills/minimax-xlsx/references/fix.md +37 -0
- package/templates/.agent/skills/minimax-xlsx/references/format.md +768 -0
- package/templates/.agent/skills/minimax-xlsx/references/ooxml-cheatsheet.md +231 -0
- package/templates/.agent/skills/minimax-xlsx/references/read-analyze.md +97 -0
- package/templates/.agent/skills/minimax-xlsx/references/validate.md +772 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/formula_check.py +422 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/libreoffice_recalc.py +248 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/shared_strings_builder.py +163 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/style_audit.py +575 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_add_column.py +395 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_insert_row.py +274 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_pack.py +87 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_reader.py +362 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_shift_rows.py +396 -0
- package/templates/.agent/skills/minimax-xlsx/scripts/xlsx_unpack.py +130 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
- package/templates/.agent/skills/minimax-xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
- package/templates/.agent/skills/pptx-generator/SKILL.md +249 -0
- package/templates/.agent/skills/pptx-generator/references/design-system.md +392 -0
- package/templates/.agent/skills/pptx-generator/references/editing.md +162 -0
- package/templates/.agent/skills/pptx-generator/references/pitfalls.md +112 -0
- package/templates/.agent/skills/pptx-generator/references/pptxgenjs.md +420 -0
- package/templates/.agent/skills/pptx-generator/references/slide-types.md +413 -0
- package/templates/.agent/skills/tutorial-video-expert/SKILL.md +88 -0
- package/templates/.agent/skills/ui-ux-pro-max/SKILL.md +170 -585
- package/templates/.agent/skills/vision-analysis/SKILL.md +174 -0
- package/templates/.agent/workflows/analyze.md +3 -0
- package/templates/.agent/workflows/brand-report.md +44 -0
- package/templates/.agent/workflows/report.md +49 -0
- package/templates/.agent/agents/backend-specialist.md +0 -263
- package/templates/.agent/agents/database-architect.md +0 -226
- package/templates/.agent/agents/debugger.md +0 -225
- package/templates/.agent/agents/devops-engineer.md +0 -242
- package/templates/.agent/agents/frontend-specialist.md +0 -527
- package/templates/.agent/agents/game-developer.md +0 -162
- package/templates/.agent/agents/mobile-developer.md +0 -377
- package/templates/.agent/agents/penetration-tester.md +0 -188
- package/templates/.agent/agents/security-auditor.md +0 -170
- package/templates/.agent/agents/test-engineer.md +0 -158
- package/templates/.agent/skills/api-patterns/SKILL.md +0 -81
- package/templates/.agent/skills/api-patterns/api-style.md +0 -42
- package/templates/.agent/skills/api-patterns/auth.md +0 -24
- package/templates/.agent/skills/api-patterns/documentation.md +0 -26
- package/templates/.agent/skills/api-patterns/graphql.md +0 -41
- package/templates/.agent/skills/api-patterns/rate-limiting.md +0 -31
- package/templates/.agent/skills/api-patterns/response.md +0 -37
- package/templates/.agent/skills/api-patterns/rest.md +0 -40
- package/templates/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
- package/templates/.agent/skills/api-patterns/security-testing.md +0 -122
- package/templates/.agent/skills/api-patterns/trpc.md +0 -41
- package/templates/.agent/skills/api-patterns/versioning.md +0 -22
- package/templates/.agent/skills/app-builder/SKILL.md +0 -75
- package/templates/.agent/skills/app-builder/agent-coordination.md +0 -71
- package/templates/.agent/skills/app-builder/feature-building.md +0 -53
- package/templates/.agent/skills/app-builder/project-detection.md +0 -34
- package/templates/.agent/skills/app-builder/scaffolding.md +0 -118
- package/templates/.agent/skills/app-builder/tech-stack.md +0 -40
- package/templates/.agent/skills/app-builder/templates/SKILL.md +0 -39
- package/templates/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
- package/templates/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
- package/templates/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
- package/templates/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
- package/templates/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
- package/templates/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
- package/templates/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
- package/templates/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -82
- package/templates/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -100
- package/templates/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -106
- package/templates/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -101
- package/templates/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
- package/templates/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -93
- package/templates/.agent/skills/architecture/SKILL.md +0 -55
- package/templates/.agent/skills/architecture/context-discovery.md +0 -43
- package/templates/.agent/skills/architecture/examples.md +0 -94
- package/templates/.agent/skills/architecture/pattern-selection.md +0 -68
- package/templates/.agent/skills/architecture/patterns-reference.md +0 -50
- package/templates/.agent/skills/architecture/trade-off-analysis.md +0 -77
- package/templates/.agent/skills/bash-linux/SKILL.md +0 -199
- package/templates/.agent/skills/behavioral-modes/SKILL.md +0 -242
- package/templates/.agent/skills/clean-code/SKILL.md +0 -201
- package/templates/.agent/skills/code-review-checklist/SKILL.md +0 -109
- package/templates/.agent/skills/database-design/SKILL.md +0 -52
- package/templates/.agent/skills/database-design/database-selection.md +0 -43
- package/templates/.agent/skills/database-design/indexing.md +0 -39
- package/templates/.agent/skills/database-design/migrations.md +0 -48
- package/templates/.agent/skills/database-design/optimization.md +0 -36
- package/templates/.agent/skills/database-design/orm-selection.md +0 -30
- package/templates/.agent/skills/database-design/schema-design.md +0 -56
- package/templates/.agent/skills/database-design/scripts/schema_validator.py +0 -172
- package/templates/.agent/skills/deployment-procedures/SKILL.md +0 -241
- package/templates/.agent/skills/docker-expert/SKILL.md +0 -409
- package/templates/.agent/skills/game-development/2d-games/SKILL.md +0 -119
- package/templates/.agent/skills/game-development/3d-games/SKILL.md +0 -135
- package/templates/.agent/skills/game-development/SKILL.md +0 -167
- package/templates/.agent/skills/game-development/game-art/SKILL.md +0 -185
- package/templates/.agent/skills/game-development/game-audio/SKILL.md +0 -190
- package/templates/.agent/skills/game-development/game-design/SKILL.md +0 -129
- package/templates/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
- package/templates/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
- package/templates/.agent/skills/game-development/pc-games/SKILL.md +0 -144
- package/templates/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
- package/templates/.agent/skills/game-development/web-games/SKILL.md +0 -150
- package/templates/.agent/skills/lint-and-validate/SKILL.md +0 -45
- package/templates/.agent/skills/lint-and-validate/scripts/lint_runner.py +0 -172
- package/templates/.agent/skills/lint-and-validate/scripts/type_coverage.py +0 -173
- package/templates/.agent/skills/mcp-builder/SKILL.md +0 -176
- package/templates/.agent/skills/nestjs-expert/SKILL.md +0 -552
- package/templates/.agent/skills/nextjs-best-practices/SKILL.md +0 -203
- package/templates/.agent/skills/nodejs-best-practices/SKILL.md +0 -333
- package/templates/.agent/skills/parallel-agents/SKILL.md +0 -175
- package/templates/.agent/skills/performance-profiling/SKILL.md +0 -143
- package/templates/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +0 -76
- package/templates/.agent/skills/powershell-windows/SKILL.md +0 -167
- package/templates/.agent/skills/prisma-expert/SKILL.md +0 -355
- package/templates/.agent/skills/python-patterns/SKILL.md +0 -441
- package/templates/.agent/skills/react-patterns/SKILL.md +0 -198
- package/templates/.agent/skills/red-team-tactics/SKILL.md +0 -199
- package/templates/.agent/skills/server-management/SKILL.md +0 -161
- package/templates/.agent/skills/systematic-debugging/SKILL.md +0 -109
- package/templates/.agent/skills/tdd-workflow/SKILL.md +0 -149
- package/templates/.agent/skills/testing-patterns/SKILL.md +0 -178
- package/templates/.agent/skills/testing-patterns/scripts/test_runner.py +0 -219
- package/templates/.agent/skills/typescript-expert/SKILL.md +0 -429
- package/templates/.agent/skills/vue-expert/SKILL.md +0 -374
- package/templates/.agent/skills/vulnerability-scanner/SKILL.md +0 -276
- package/templates/.agent/skills/vulnerability-scanner/checklists.md +0 -121
- package/templates/.agent/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
- package/templates/.agent/skills/webapp-testing/SKILL.md +0 -187
- package/templates/.agent/skills/webapp-testing/scripts/playwright_runner.py +0 -173
- package/templates/.agent/workflows/debug.md +0 -103
- package/templates/.agent/workflows/deploy.md +0 -176
- package/templates/.agent/workflows/enhance.md +0 -63
- package/templates/.agent/workflows/test.md +0 -144
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
using DocumentFormat.OpenXml;
|
|
2
|
+
using DocumentFormat.OpenXml.Packaging;
|
|
3
|
+
using DocumentFormat.OpenXml.Wordprocessing;
|
|
4
|
+
using A = DocumentFormat.OpenXml.Drawing;
|
|
5
|
+
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
|
|
6
|
+
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
|
|
7
|
+
|
|
8
|
+
namespace MiniMaxAIDocx.Core.Samples;
|
|
9
|
+
|
|
10
|
+
/// <summary>
|
|
11
|
+
/// Comprehensive reference for OpenXML headers, footers, and page numbers.
|
|
12
|
+
///
|
|
13
|
+
/// Architecture:
|
|
14
|
+
/// - Headers/footers live in separate HeaderPart/FooterPart containers.
|
|
15
|
+
/// - They are linked to sections via HeaderReference/FooterReference in SectionProperties.
|
|
16
|
+
/// - Each reference has a Type: Default, First, Even.
|
|
17
|
+
/// - The relationship ID (r:id) connects the reference to the part.
|
|
18
|
+
///
|
|
19
|
+
/// XML structure in SectionProperties:
|
|
20
|
+
/// <w:sectPr>
|
|
21
|
+
/// <w:headerReference w:type="default" r:id="rId7"/>
|
|
22
|
+
/// <w:footerReference w:type="default" r:id="rId8"/>
|
|
23
|
+
/// <w:headerReference w:type="first" r:id="rId9"/>
|
|
24
|
+
/// <w:titlePg/> <!-- needed to activate first-page header/footer -->
|
|
25
|
+
/// </w:sectPr>
|
|
26
|
+
///
|
|
27
|
+
/// Header/Footer XML (in separate part):
|
|
28
|
+
/// <w:hdr> (or <w:ftr>)
|
|
29
|
+
/// <w:p>
|
|
30
|
+
/// <w:pPr>...</w:pPr>
|
|
31
|
+
/// <w:r><w:t>Header text</w:t></w:r>
|
|
32
|
+
/// </w:p>
|
|
33
|
+
/// </w:hdr>
|
|
34
|
+
///
|
|
35
|
+
/// Page number fields use complex field codes:
|
|
36
|
+
/// PAGE — current page number
|
|
37
|
+
/// NUMPAGES — total page count
|
|
38
|
+
/// </summary>
|
|
39
|
+
public static class HeaderFooterSamples
|
|
40
|
+
{
|
|
41
|
+
// ──────────────────────────────────────────────────────────────
|
|
42
|
+
// 1. AddSimpleHeader — basic text header
|
|
43
|
+
// ──────────────────────────────────────────────────────────────
|
|
44
|
+
/// <summary>
|
|
45
|
+
/// Adds a simple text header to the default header slot.
|
|
46
|
+
///
|
|
47
|
+
/// Steps:
|
|
48
|
+
/// 1. Create a HeaderPart on the MainDocumentPart
|
|
49
|
+
/// 2. Set its Header content (must contain at least one Paragraph)
|
|
50
|
+
/// 3. Get the relationship ID
|
|
51
|
+
/// 4. Add HeaderReference to SectionProperties with type="default"
|
|
52
|
+
///
|
|
53
|
+
/// XML in header part:
|
|
54
|
+
/// <w:hdr>
|
|
55
|
+
/// <w:p>
|
|
56
|
+
/// <w:pPr><w:jc w:val="right"/></w:pPr>
|
|
57
|
+
/// <w:r>
|
|
58
|
+
/// <w:rPr><w:color w:val="808080"/><w:sz w:val="18"/></w:rPr>
|
|
59
|
+
/// <w:t>My Document Header</w:t>
|
|
60
|
+
/// </w:r>
|
|
61
|
+
/// </w:p>
|
|
62
|
+
/// </w:hdr>
|
|
63
|
+
///
|
|
64
|
+
/// XML in sectPr:
|
|
65
|
+
/// <w:headerReference w:type="default" r:id="rIdXX"/>
|
|
66
|
+
/// </summary>
|
|
67
|
+
public static void AddSimpleHeader(MainDocumentPart mainPart, SectionProperties sectPr, string text)
|
|
68
|
+
{
|
|
69
|
+
var headerPart = mainPart.AddNewPart<HeaderPart>();
|
|
70
|
+
|
|
71
|
+
headerPart.Header = new Header(
|
|
72
|
+
new Paragraph(
|
|
73
|
+
new ParagraphProperties(
|
|
74
|
+
new Justification { Val = JustificationValues.Right }),
|
|
75
|
+
new Run(
|
|
76
|
+
new RunProperties(
|
|
77
|
+
new Color { Val = "808080" },
|
|
78
|
+
new FontSize { Val = "18" }), // 9pt (half-points)
|
|
79
|
+
new Text(text) { Space = SpaceProcessingModeValues.Preserve })));
|
|
80
|
+
headerPart.Header.Save();
|
|
81
|
+
|
|
82
|
+
var headerRefId = mainPart.GetIdOfPart(headerPart);
|
|
83
|
+
sectPr.Append(new HeaderReference
|
|
84
|
+
{
|
|
85
|
+
Type = HeaderFooterValues.Default,
|
|
86
|
+
Id = headerRefId
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ──────────────────────────────────────────────────────────────
|
|
91
|
+
// 2. AddSimpleFooter — basic text footer
|
|
92
|
+
// ──────────────────────────────────────────────────────────────
|
|
93
|
+
/// <summary>
|
|
94
|
+
/// Adds a simple text footer to the default footer slot.
|
|
95
|
+
///
|
|
96
|
+
/// XML in footer part:
|
|
97
|
+
/// <w:ftr>
|
|
98
|
+
/// <w:p>
|
|
99
|
+
/// <w:pPr><w:jc w:val="center"/></w:pPr>
|
|
100
|
+
/// <w:r><w:t>Confidential</w:t></w:r>
|
|
101
|
+
/// </w:p>
|
|
102
|
+
/// </w:ftr>
|
|
103
|
+
///
|
|
104
|
+
/// XML in sectPr:
|
|
105
|
+
/// <w:footerReference w:type="default" r:id="rIdXX"/>
|
|
106
|
+
/// </summary>
|
|
107
|
+
public static void AddSimpleFooter(MainDocumentPart mainPart, SectionProperties sectPr, string text)
|
|
108
|
+
{
|
|
109
|
+
var footerPart = mainPart.AddNewPart<FooterPart>();
|
|
110
|
+
|
|
111
|
+
footerPart.Footer = new Footer(
|
|
112
|
+
new Paragraph(
|
|
113
|
+
new ParagraphProperties(
|
|
114
|
+
new Justification { Val = JustificationValues.Center }),
|
|
115
|
+
new Run(
|
|
116
|
+
new RunProperties(
|
|
117
|
+
new Color { Val = "808080" },
|
|
118
|
+
new FontSize { Val = "18" }),
|
|
119
|
+
new Text(text) { Space = SpaceProcessingModeValues.Preserve })));
|
|
120
|
+
footerPart.Footer.Save();
|
|
121
|
+
|
|
122
|
+
var footerRefId = mainPart.GetIdOfPart(footerPart);
|
|
123
|
+
sectPr.Append(new FooterReference
|
|
124
|
+
{
|
|
125
|
+
Type = HeaderFooterValues.Default,
|
|
126
|
+
Id = footerRefId
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ──────────────────────────────────────────────────────────────
|
|
131
|
+
// 3. AddPageNumberFooter — centered page number
|
|
132
|
+
// ──────────────────────────────────────────────────────────────
|
|
133
|
+
/// <summary>
|
|
134
|
+
/// Adds a centered page number footer using the PAGE field code.
|
|
135
|
+
///
|
|
136
|
+
/// Field code pattern (3 runs):
|
|
137
|
+
/// Run 1: FieldChar Begin
|
|
138
|
+
/// Run 2: FieldCode " PAGE "
|
|
139
|
+
/// Run 3: FieldChar End
|
|
140
|
+
///
|
|
141
|
+
/// XML:
|
|
142
|
+
/// <w:ftr>
|
|
143
|
+
/// <w:p>
|
|
144
|
+
/// <w:pPr><w:jc w:val="center"/></w:pPr>
|
|
145
|
+
/// <w:r><w:fldChar w:fldCharType="begin"/></w:r>
|
|
146
|
+
/// <w:r><w:instrText xml:space="preserve"> PAGE </w:instrText></w:r>
|
|
147
|
+
/// <w:r><w:fldChar w:fldCharType="end"/></w:r>
|
|
148
|
+
/// </w:p>
|
|
149
|
+
/// </w:ftr>
|
|
150
|
+
///
|
|
151
|
+
/// GOTCHA: FieldCode text MUST have leading/trailing spaces: " PAGE ", not "PAGE".
|
|
152
|
+
/// GOTCHA: Use Space = SpaceProcessingModeValues.Preserve on FieldCode to keep spaces.
|
|
153
|
+
/// </summary>
|
|
154
|
+
public static void AddPageNumberFooter(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
155
|
+
{
|
|
156
|
+
var footerPart = mainPart.AddNewPart<FooterPart>();
|
|
157
|
+
|
|
158
|
+
var paragraph = new Paragraph(
|
|
159
|
+
new ParagraphProperties(
|
|
160
|
+
new Justification { Val = JustificationValues.Center }));
|
|
161
|
+
|
|
162
|
+
// PAGE field: Begin → InstrText → End
|
|
163
|
+
paragraph.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
164
|
+
paragraph.Append(new Run(new FieldCode(" PAGE ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
165
|
+
paragraph.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
166
|
+
|
|
167
|
+
footerPart.Footer = new Footer(paragraph);
|
|
168
|
+
footerPart.Footer.Save();
|
|
169
|
+
|
|
170
|
+
var footerRefId = mainPart.GetIdOfPart(footerPart);
|
|
171
|
+
sectPr.Append(new FooterReference
|
|
172
|
+
{
|
|
173
|
+
Type = HeaderFooterValues.Default,
|
|
174
|
+
Id = footerRefId
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ──────────────────────────────────────────────────────────────
|
|
179
|
+
// 4. AddPageXofYFooter — "Page X of Y"
|
|
180
|
+
// ──────────────────────────────────────────────────────────────
|
|
181
|
+
/// <summary>
|
|
182
|
+
/// Adds a footer with "Page X of Y" format using PAGE and NUMPAGES field codes.
|
|
183
|
+
///
|
|
184
|
+
/// XML:
|
|
185
|
+
/// <w:ftr>
|
|
186
|
+
/// <w:p>
|
|
187
|
+
/// <w:pPr><w:jc w:val="center"/></w:pPr>
|
|
188
|
+
/// <w:r><w:t xml:space="preserve">Page </w:t></w:r>
|
|
189
|
+
/// <w:r><w:fldChar w:fldCharType="begin"/></w:r>
|
|
190
|
+
/// <w:r><w:instrText xml:space="preserve"> PAGE </w:instrText></w:r>
|
|
191
|
+
/// <w:r><w:fldChar w:fldCharType="end"/></w:r>
|
|
192
|
+
/// <w:r><w:t xml:space="preserve"> of </w:t></w:r>
|
|
193
|
+
/// <w:r><w:fldChar w:fldCharType="begin"/></w:r>
|
|
194
|
+
/// <w:r><w:instrText xml:space="preserve"> NUMPAGES </w:instrText></w:r>
|
|
195
|
+
/// <w:r><w:fldChar w:fldCharType="end"/></w:r>
|
|
196
|
+
/// </w:p>
|
|
197
|
+
/// </w:ftr>
|
|
198
|
+
/// </summary>
|
|
199
|
+
public static void AddPageXofYFooter(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
200
|
+
{
|
|
201
|
+
var footerPart = mainPart.AddNewPart<FooterPart>();
|
|
202
|
+
|
|
203
|
+
var paragraph = new Paragraph(
|
|
204
|
+
new ParagraphProperties(
|
|
205
|
+
new Justification { Val = JustificationValues.Center }));
|
|
206
|
+
|
|
207
|
+
// "Page "
|
|
208
|
+
paragraph.Append(new Run(new Text("Page ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
209
|
+
|
|
210
|
+
// PAGE field
|
|
211
|
+
paragraph.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
212
|
+
paragraph.Append(new Run(new FieldCode(" PAGE ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
213
|
+
paragraph.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
214
|
+
|
|
215
|
+
// " of "
|
|
216
|
+
paragraph.Append(new Run(new Text(" of ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
217
|
+
|
|
218
|
+
// NUMPAGES field
|
|
219
|
+
paragraph.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
220
|
+
paragraph.Append(new Run(new FieldCode(" NUMPAGES ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
221
|
+
paragraph.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
222
|
+
|
|
223
|
+
footerPart.Footer = new Footer(paragraph);
|
|
224
|
+
footerPart.Footer.Save();
|
|
225
|
+
|
|
226
|
+
var footerRefId = mainPart.GetIdOfPart(footerPart);
|
|
227
|
+
sectPr.Append(new FooterReference
|
|
228
|
+
{
|
|
229
|
+
Type = HeaderFooterValues.Default,
|
|
230
|
+
Id = footerRefId
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ──────────────────────────────────────────────────────────────
|
|
235
|
+
// 5. AddDifferentFirstPageHeader — TitlePage element
|
|
236
|
+
// ──────────────────────────────────────────────────────────────
|
|
237
|
+
/// <summary>
|
|
238
|
+
/// Adds a different header for the first page vs. subsequent pages.
|
|
239
|
+
///
|
|
240
|
+
/// Requires:
|
|
241
|
+
/// 1. <w:titlePg/> in SectionProperties to enable first-page header/footer
|
|
242
|
+
/// 2. HeaderReference with Type="first" for the first page header
|
|
243
|
+
/// 3. HeaderReference with Type="default" for subsequent pages
|
|
244
|
+
///
|
|
245
|
+
/// XML in sectPr:
|
|
246
|
+
/// <w:sectPr>
|
|
247
|
+
/// <w:headerReference w:type="first" r:id="rIdFirst"/>
|
|
248
|
+
/// <w:headerReference w:type="default" r:id="rIdDefault"/>
|
|
249
|
+
/// <w:titlePg/> <!-- CRITICAL: without this, first-page header is ignored -->
|
|
250
|
+
/// </w:sectPr>
|
|
251
|
+
///
|
|
252
|
+
/// GOTCHA: Without <w:titlePg/>, the "first" type header is completely ignored.
|
|
253
|
+
/// GOTCHA: If you want a blank first-page header, you still need a HeaderPart
|
|
254
|
+
/// with an empty Paragraph — just don't add text to it.
|
|
255
|
+
/// </summary>
|
|
256
|
+
public static void AddDifferentFirstPageHeader(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
257
|
+
{
|
|
258
|
+
// First page header: e.g., cover page with large title
|
|
259
|
+
var firstHeaderPart = mainPart.AddNewPart<HeaderPart>();
|
|
260
|
+
firstHeaderPart.Header = new Header(
|
|
261
|
+
new Paragraph(
|
|
262
|
+
new ParagraphProperties(
|
|
263
|
+
new Justification { Val = JustificationValues.Center }),
|
|
264
|
+
new Run(
|
|
265
|
+
new RunProperties(
|
|
266
|
+
new Bold(),
|
|
267
|
+
new FontSize { Val = "32" }), // 16pt
|
|
268
|
+
new Text("COMPANY CONFIDENTIAL"))));
|
|
269
|
+
firstHeaderPart.Header.Save();
|
|
270
|
+
|
|
271
|
+
// Default header for subsequent pages
|
|
272
|
+
var defaultHeaderPart = mainPart.AddNewPart<HeaderPart>();
|
|
273
|
+
defaultHeaderPart.Header = new Header(
|
|
274
|
+
new Paragraph(
|
|
275
|
+
new ParagraphProperties(
|
|
276
|
+
new Justification { Val = JustificationValues.Right }),
|
|
277
|
+
new Run(
|
|
278
|
+
new RunProperties(
|
|
279
|
+
new FontSize { Val = "18" }), // 9pt
|
|
280
|
+
new Text("Internal Document"))));
|
|
281
|
+
defaultHeaderPart.Header.Save();
|
|
282
|
+
|
|
283
|
+
// Link both headers to section
|
|
284
|
+
sectPr.Append(new HeaderReference
|
|
285
|
+
{
|
|
286
|
+
Type = HeaderFooterValues.First,
|
|
287
|
+
Id = mainPart.GetIdOfPart(firstHeaderPart)
|
|
288
|
+
});
|
|
289
|
+
sectPr.Append(new HeaderReference
|
|
290
|
+
{
|
|
291
|
+
Type = HeaderFooterValues.Default,
|
|
292
|
+
Id = mainPart.GetIdOfPart(defaultHeaderPart)
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// CRITICAL: Enable first page header/footer
|
|
296
|
+
sectPr.Append(new TitlePage());
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// ──────────────────────────────────────────────────────────────
|
|
300
|
+
// 6. AddEvenOddHeaders — EvenAndOddHeaders in Settings
|
|
301
|
+
// ──────────────────────────────────────────────────────────────
|
|
302
|
+
/// <summary>
|
|
303
|
+
/// Creates different headers for even and odd pages (e.g., for book-style printing).
|
|
304
|
+
///
|
|
305
|
+
/// Requires:
|
|
306
|
+
/// 1. <w:evenAndOddHeaders/> in document Settings (DocumentSettingsPart)
|
|
307
|
+
/// 2. HeaderReference with Type="default" for odd pages
|
|
308
|
+
/// 3. HeaderReference with Type="even" for even pages
|
|
309
|
+
///
|
|
310
|
+
/// XML in settings.xml:
|
|
311
|
+
/// <w:settings>
|
|
312
|
+
/// <w:evenAndOddHeaders/>
|
|
313
|
+
/// </w:settings>
|
|
314
|
+
///
|
|
315
|
+
/// XML in sectPr:
|
|
316
|
+
/// <w:sectPr>
|
|
317
|
+
/// <w:headerReference w:type="default" r:id="rIdOdd"/>
|
|
318
|
+
/// <w:headerReference w:type="even" r:id="rIdEven"/>
|
|
319
|
+
/// </w:sectPr>
|
|
320
|
+
///
|
|
321
|
+
/// GOTCHA: "default" means ODD pages when evenAndOddHeaders is enabled.
|
|
322
|
+
/// GOTCHA: Without the Settings flag, the "even" header is ignored entirely.
|
|
323
|
+
/// </summary>
|
|
324
|
+
public static void AddEvenOddHeaders(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
325
|
+
{
|
|
326
|
+
// Enable even/odd header distinction in document settings
|
|
327
|
+
var settingsPart = mainPart.DocumentSettingsPart
|
|
328
|
+
?? mainPart.AddNewPart<DocumentSettingsPart>();
|
|
329
|
+
if (settingsPart.Settings == null)
|
|
330
|
+
settingsPart.Settings = new Settings();
|
|
331
|
+
|
|
332
|
+
// Add EvenAndOddHeaders if not already present
|
|
333
|
+
if (settingsPart.Settings.GetFirstChild<EvenAndOddHeaders>() == null)
|
|
334
|
+
{
|
|
335
|
+
settingsPart.Settings.Append(new EvenAndOddHeaders());
|
|
336
|
+
}
|
|
337
|
+
settingsPart.Settings.Save();
|
|
338
|
+
|
|
339
|
+
// Odd page header (Type="default" means odd when even/odd is enabled)
|
|
340
|
+
var oddHeaderPart = mainPart.AddNewPart<HeaderPart>();
|
|
341
|
+
oddHeaderPart.Header = new Header(
|
|
342
|
+
new Paragraph(
|
|
343
|
+
new ParagraphProperties(
|
|
344
|
+
new Justification { Val = JustificationValues.Right }),
|
|
345
|
+
new Run(new Text("Chapter Title — Odd Page"))));
|
|
346
|
+
oddHeaderPart.Header.Save();
|
|
347
|
+
|
|
348
|
+
// Even page header
|
|
349
|
+
var evenHeaderPart = mainPart.AddNewPart<HeaderPart>();
|
|
350
|
+
evenHeaderPart.Header = new Header(
|
|
351
|
+
new Paragraph(
|
|
352
|
+
new ParagraphProperties(
|
|
353
|
+
new Justification { Val = JustificationValues.Left }),
|
|
354
|
+
new Run(new Text("Book Title — Even Page"))));
|
|
355
|
+
evenHeaderPart.Header.Save();
|
|
356
|
+
|
|
357
|
+
// Link to section
|
|
358
|
+
sectPr.Append(new HeaderReference
|
|
359
|
+
{
|
|
360
|
+
Type = HeaderFooterValues.Default, // = odd pages
|
|
361
|
+
Id = mainPart.GetIdOfPart(oddHeaderPart)
|
|
362
|
+
});
|
|
363
|
+
sectPr.Append(new HeaderReference
|
|
364
|
+
{
|
|
365
|
+
Type = HeaderFooterValues.Even,
|
|
366
|
+
Id = mainPart.GetIdOfPart(evenHeaderPart)
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// ──────────────────────────────────────────────────────────────
|
|
371
|
+
// 7. AddHeaderWithLogo — image in header
|
|
372
|
+
// ──────────────────────────────────────────────────────────────
|
|
373
|
+
/// <summary>
|
|
374
|
+
/// Adds a header containing an image (logo).
|
|
375
|
+
///
|
|
376
|
+
/// Steps:
|
|
377
|
+
/// 1. Create HeaderPart
|
|
378
|
+
/// 2. Add ImagePart to the HeaderPart (NOT to MainDocumentPart)
|
|
379
|
+
/// 3. Feed the image stream
|
|
380
|
+
/// 4. Build Drawing element with inline image
|
|
381
|
+
/// 5. Link HeaderPart to sectPr
|
|
382
|
+
///
|
|
383
|
+
/// Image sizing uses EMU (English Metric Units):
|
|
384
|
+
/// 914400 EMU = 1 inch
|
|
385
|
+
/// 360000 EMU = 1 cm
|
|
386
|
+
///
|
|
387
|
+
/// XML for inline image:
|
|
388
|
+
/// <w:drawing>
|
|
389
|
+
/// <wp:inline distT="0" distB="0" distL="0" distR="0">
|
|
390
|
+
/// <wp:extent cx="914400" cy="457200"/>
|
|
391
|
+
/// <wp:docPr id="1" name="Logo"/>
|
|
392
|
+
/// <a:graphic>
|
|
393
|
+
/// <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
|
394
|
+
/// <pic:pic>
|
|
395
|
+
/// <pic:nvPicPr>...</pic:nvPicPr>
|
|
396
|
+
/// <pic:blipFill><a:blip r:embed="rIdImg"/></pic:blipFill>
|
|
397
|
+
/// <pic:spPr>...</pic:spPr>
|
|
398
|
+
/// </pic:pic>
|
|
399
|
+
/// </a:graphicData>
|
|
400
|
+
/// </a:graphic>
|
|
401
|
+
/// </wp:inline>
|
|
402
|
+
/// </w:drawing>
|
|
403
|
+
///
|
|
404
|
+
/// GOTCHA: The ImagePart must be added to the HeaderPart, not the MainDocumentPart.
|
|
405
|
+
/// If you add it to MainDocumentPart, the relationship ID won't resolve in the header.
|
|
406
|
+
/// </summary>
|
|
407
|
+
public static void AddHeaderWithLogo(MainDocumentPart mainPart, SectionProperties sectPr, string imagePath)
|
|
408
|
+
{
|
|
409
|
+
var headerPart = mainPart.AddNewPart<HeaderPart>();
|
|
410
|
+
|
|
411
|
+
// Add image part to the HEADER part (not main document part)
|
|
412
|
+
var imagePart = headerPart.AddImagePart(ImagePartType.Png);
|
|
413
|
+
using (var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
|
|
414
|
+
{
|
|
415
|
+
imagePart.FeedData(stream);
|
|
416
|
+
}
|
|
417
|
+
var imageRelId = headerPart.GetIdOfPart(imagePart);
|
|
418
|
+
|
|
419
|
+
// Image dimensions in EMU: 1 inch wide x 0.5 inch tall
|
|
420
|
+
long widthEmu = 914400; // 1 inch
|
|
421
|
+
long heightEmu = 457200; // 0.5 inch
|
|
422
|
+
|
|
423
|
+
// Build the Drawing element with inline image
|
|
424
|
+
var drawing = new Drawing(
|
|
425
|
+
new DW.Inline(
|
|
426
|
+
new DW.Extent { Cx = widthEmu, Cy = heightEmu },
|
|
427
|
+
new DW.EffectExtent { LeftEdge = 0, TopEdge = 0, RightEdge = 0, BottomEdge = 0 },
|
|
428
|
+
new DW.DocProperties { Id = 1U, Name = "Logo" },
|
|
429
|
+
new A.Graphic(
|
|
430
|
+
new A.GraphicData(
|
|
431
|
+
new PIC.Picture(
|
|
432
|
+
new PIC.NonVisualPictureProperties(
|
|
433
|
+
new PIC.NonVisualDrawingProperties { Id = 0U, Name = "logo.png" },
|
|
434
|
+
new PIC.NonVisualPictureDrawingProperties()),
|
|
435
|
+
new PIC.BlipFill(
|
|
436
|
+
new A.Blip { Embed = imageRelId },
|
|
437
|
+
new A.Stretch(new A.FillRectangle())),
|
|
438
|
+
new PIC.ShapeProperties(
|
|
439
|
+
new A.Transform2D(
|
|
440
|
+
new A.Offset { X = 0, Y = 0 },
|
|
441
|
+
new A.Extents { Cx = widthEmu, Cy = heightEmu }),
|
|
442
|
+
new A.PresetGeometry(
|
|
443
|
+
new A.AdjustValueList())
|
|
444
|
+
{ Preset = A.ShapeTypeValues.Rectangle }))
|
|
445
|
+
) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
|
|
446
|
+
)
|
|
447
|
+
{
|
|
448
|
+
DistanceFromTop = 0U,
|
|
449
|
+
DistanceFromBottom = 0U,
|
|
450
|
+
DistanceFromLeft = 0U,
|
|
451
|
+
DistanceFromRight = 0U
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
headerPart.Header = new Header(
|
|
455
|
+
new Paragraph(new Run(drawing)));
|
|
456
|
+
headerPart.Header.Save();
|
|
457
|
+
|
|
458
|
+
var headerRefId = mainPart.GetIdOfPart(headerPart);
|
|
459
|
+
sectPr.Append(new HeaderReference
|
|
460
|
+
{
|
|
461
|
+
Type = HeaderFooterValues.Default,
|
|
462
|
+
Id = headerRefId
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// ──────────────────────────────────────────────────────────────
|
|
467
|
+
// 8. AddTableLayoutHeader — 3-column invisible table
|
|
468
|
+
// ──────────────────────────────────────────────────────────────
|
|
469
|
+
/// <summary>
|
|
470
|
+
/// Creates a header with a 3-column invisible table for precise layout:
|
|
471
|
+
/// Left cell: Logo placeholder text
|
|
472
|
+
/// Center cell: Document title (centered)
|
|
473
|
+
/// Right cell: Page number (right-aligned)
|
|
474
|
+
///
|
|
475
|
+
/// The table has no borders, so it's invisible but provides column alignment.
|
|
476
|
+
///
|
|
477
|
+
/// XML structure:
|
|
478
|
+
/// <w:hdr>
|
|
479
|
+
/// <w:tbl>
|
|
480
|
+
/// <w:tblPr>
|
|
481
|
+
/// <w:tblW w:w="5000" w:type="pct"/>
|
|
482
|
+
/// <w:tblBorders>
|
|
483
|
+
/// <w:top w:val="none"/> <w:left w:val="none"/> ...
|
|
484
|
+
/// </w:tblBorders>
|
|
485
|
+
/// </w:tblPr>
|
|
486
|
+
/// <w:tblGrid>
|
|
487
|
+
/// <w:gridCol w:w="3120"/> <w:gridCol w:w="3120"/> <w:gridCol w:w="3120"/>
|
|
488
|
+
/// </w:tblGrid>
|
|
489
|
+
/// <w:tr>
|
|
490
|
+
/// <w:tc> <!-- left: logo text --> </w:tc>
|
|
491
|
+
/// <w:tc> <!-- center: title --> </w:tc>
|
|
492
|
+
/// <w:tc> <!-- right: page num --> </w:tc>
|
|
493
|
+
/// </w:tr>
|
|
494
|
+
/// </w:tbl>
|
|
495
|
+
/// </w:hdr>
|
|
496
|
+
/// </summary>
|
|
497
|
+
public static void AddTableLayoutHeader(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
498
|
+
{
|
|
499
|
+
var headerPart = mainPart.AddNewPart<HeaderPart>();
|
|
500
|
+
|
|
501
|
+
// Invisible table (no borders)
|
|
502
|
+
var table = new Table();
|
|
503
|
+
var tblPr = new TableProperties(
|
|
504
|
+
new TableWidth { Width = "5000", Type = TableWidthUnitValues.Pct },
|
|
505
|
+
new TableBorders(
|
|
506
|
+
new TopBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
507
|
+
new LeftBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
508
|
+
new BottomBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
509
|
+
new RightBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
510
|
+
new InsideHorizontalBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
511
|
+
new InsideVerticalBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" }
|
|
512
|
+
),
|
|
513
|
+
// Fixed layout so columns don't shift
|
|
514
|
+
new TableLayout { Type = TableLayoutValues.Fixed });
|
|
515
|
+
table.Append(tblPr);
|
|
516
|
+
|
|
517
|
+
var grid = new TableGrid(
|
|
518
|
+
new GridColumn { Width = "3120" },
|
|
519
|
+
new GridColumn { Width = "3120" },
|
|
520
|
+
new GridColumn { Width = "3120" });
|
|
521
|
+
table.Append(grid);
|
|
522
|
+
|
|
523
|
+
var row = new TableRow();
|
|
524
|
+
|
|
525
|
+
// Left cell: logo/company name
|
|
526
|
+
var leftCell = new TableCell(
|
|
527
|
+
new Paragraph(
|
|
528
|
+
new ParagraphProperties(
|
|
529
|
+
new Justification { Val = JustificationValues.Left }),
|
|
530
|
+
new Run(
|
|
531
|
+
new RunProperties(new Bold(), new FontSize { Val = "18" }),
|
|
532
|
+
new Text("ACME Corp"))));
|
|
533
|
+
row.Append(leftCell);
|
|
534
|
+
|
|
535
|
+
// Center cell: document title
|
|
536
|
+
var centerCell = new TableCell(
|
|
537
|
+
new Paragraph(
|
|
538
|
+
new ParagraphProperties(
|
|
539
|
+
new Justification { Val = JustificationValues.Center }),
|
|
540
|
+
new Run(
|
|
541
|
+
new RunProperties(new FontSize { Val = "18" }),
|
|
542
|
+
new Text("Technical Report"))));
|
|
543
|
+
row.Append(centerCell);
|
|
544
|
+
|
|
545
|
+
// Right cell: page number
|
|
546
|
+
var pageNumPara = new Paragraph(
|
|
547
|
+
new ParagraphProperties(
|
|
548
|
+
new Justification { Val = JustificationValues.Right }));
|
|
549
|
+
pageNumPara.Append(new Run(
|
|
550
|
+
new RunProperties(new FontSize { Val = "18" }),
|
|
551
|
+
new Text("Page ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
552
|
+
pageNumPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
553
|
+
pageNumPara.Append(new Run(new FieldCode(" PAGE ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
554
|
+
pageNumPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
555
|
+
|
|
556
|
+
var rightCell = new TableCell(pageNumPara);
|
|
557
|
+
row.Append(rightCell);
|
|
558
|
+
|
|
559
|
+
table.Append(row);
|
|
560
|
+
|
|
561
|
+
headerPart.Header = new Header(table);
|
|
562
|
+
headerPart.Header.Save();
|
|
563
|
+
|
|
564
|
+
var headerRefId = mainPart.GetIdOfPart(headerPart);
|
|
565
|
+
sectPr.Append(new HeaderReference
|
|
566
|
+
{
|
|
567
|
+
Type = HeaderFooterValues.Default,
|
|
568
|
+
Id = headerRefId
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// ──────────────────────────────────────────────────────────────
|
|
573
|
+
// 9. AddChineseGongWenFooter — "-X-" format, SimSun 14pt
|
|
574
|
+
// ──────────────────────────────────────────────────────────────
|
|
575
|
+
/// <summary>
|
|
576
|
+
/// Adds a Chinese government document (公文) style footer:
|
|
577
|
+
/// - Page number in "-X-" format (e.g., "- 1 -")
|
|
578
|
+
/// - Centered at bottom
|
|
579
|
+
/// - SimSun (宋体) font, 14pt (Chinese 四号)
|
|
580
|
+
///
|
|
581
|
+
/// XML:
|
|
582
|
+
/// <w:ftr>
|
|
583
|
+
/// <w:p>
|
|
584
|
+
/// <w:pPr><w:jc w:val="center"/></w:pPr>
|
|
585
|
+
/// <w:r>
|
|
586
|
+
/// <w:rPr>
|
|
587
|
+
/// <w:rFonts w:ascii="SimSun" w:eastAsia="SimSun"/>
|
|
588
|
+
/// <w:sz w:val="28"/>
|
|
589
|
+
/// </w:rPr>
|
|
590
|
+
/// <w:t xml:space="preserve">- </w:t>
|
|
591
|
+
/// </w:r>
|
|
592
|
+
/// <w:r>..PAGE field..</w:r>
|
|
593
|
+
/// <w:r>
|
|
594
|
+
/// <w:rPr>...</w:rPr>
|
|
595
|
+
/// <w:t xml:space="preserve"> -</w:t>
|
|
596
|
+
/// </w:r>
|
|
597
|
+
/// </w:p>
|
|
598
|
+
/// </w:ftr>
|
|
599
|
+
///
|
|
600
|
+
/// Chinese font size reference:
|
|
601
|
+
/// 四号 = 14pt = sz val="28" (half-points)
|
|
602
|
+
/// 小四 = 12pt = sz val="24"
|
|
603
|
+
/// 五号 = 10.5pt = sz val="21"
|
|
604
|
+
/// </summary>
|
|
605
|
+
public static void AddChineseGongWenFooter(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
606
|
+
{
|
|
607
|
+
var footerPart = mainPart.AddNewPart<FooterPart>();
|
|
608
|
+
|
|
609
|
+
// Common run properties for the footer: SimSun 14pt (四号)
|
|
610
|
+
// 14pt = 28 half-points
|
|
611
|
+
RunProperties MakeGongWenRunProps() => new RunProperties(
|
|
612
|
+
new RunFonts { Ascii = "SimSun", EastAsia = "SimSun", HighAnsi = "SimSun" },
|
|
613
|
+
new FontSize { Val = "28" },
|
|
614
|
+
new FontSizeComplexScript { Val = "28" });
|
|
615
|
+
|
|
616
|
+
var paragraph = new Paragraph(
|
|
617
|
+
new ParagraphProperties(
|
|
618
|
+
new Justification { Val = JustificationValues.Center }));
|
|
619
|
+
|
|
620
|
+
// "- " prefix
|
|
621
|
+
paragraph.Append(new Run(
|
|
622
|
+
MakeGongWenRunProps(),
|
|
623
|
+
new Text("- ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
624
|
+
|
|
625
|
+
// PAGE field with same formatting
|
|
626
|
+
paragraph.Append(new Run(
|
|
627
|
+
MakeGongWenRunProps(),
|
|
628
|
+
new FieldChar { FieldCharType = FieldCharValues.Begin }));
|
|
629
|
+
paragraph.Append(new Run(
|
|
630
|
+
MakeGongWenRunProps(),
|
|
631
|
+
new FieldCode(" PAGE ") { Space = SpaceProcessingModeValues.Preserve }));
|
|
632
|
+
paragraph.Append(new Run(
|
|
633
|
+
MakeGongWenRunProps(),
|
|
634
|
+
new FieldChar { FieldCharType = FieldCharValues.End }));
|
|
635
|
+
|
|
636
|
+
// " -" suffix
|
|
637
|
+
paragraph.Append(new Run(
|
|
638
|
+
MakeGongWenRunProps(),
|
|
639
|
+
new Text(" -") { Space = SpaceProcessingModeValues.Preserve }));
|
|
640
|
+
|
|
641
|
+
footerPart.Footer = new Footer(paragraph);
|
|
642
|
+
footerPart.Footer.Save();
|
|
643
|
+
|
|
644
|
+
var footerRefId = mainPart.GetIdOfPart(footerPart);
|
|
645
|
+
sectPr.Append(new FooterReference
|
|
646
|
+
{
|
|
647
|
+
Type = HeaderFooterValues.Default,
|
|
648
|
+
Id = footerRefId
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// ──────────────────────────────────────────────────────────────
|
|
653
|
+
// 10. AddHeaderWithHorizontalLine — bottom border line
|
|
654
|
+
// ──────────────────────────────────────────────────────────────
|
|
655
|
+
/// <summary>
|
|
656
|
+
/// Adds a header with a horizontal line (bottom border) beneath the text.
|
|
657
|
+
/// This is a common style: header text with a line separating it from content.
|
|
658
|
+
///
|
|
659
|
+
/// The line is achieved via a paragraph bottom border in the header, NOT a
|
|
660
|
+
/// separate drawing element.
|
|
661
|
+
///
|
|
662
|
+
/// XML:
|
|
663
|
+
/// <w:hdr>
|
|
664
|
+
/// <w:p>
|
|
665
|
+
/// <w:pPr>
|
|
666
|
+
/// <w:pBdr>
|
|
667
|
+
/// <w:bottom w:val="single" w:sz="6" w:space="1" w:color="000000"/>
|
|
668
|
+
/// </w:pBdr>
|
|
669
|
+
/// <w:jc w:val="center"/>
|
|
670
|
+
/// </w:pPr>
|
|
671
|
+
/// <w:r><w:t>Document Header</w:t></w:r>
|
|
672
|
+
/// </w:p>
|
|
673
|
+
/// </w:hdr>
|
|
674
|
+
///
|
|
675
|
+
/// Border space attribute: space between text and border line, in points.
|
|
676
|
+
/// Border size: in eighth-points (6 = 0.75pt).
|
|
677
|
+
/// </summary>
|
|
678
|
+
public static void AddHeaderWithHorizontalLine(MainDocumentPart mainPart, SectionProperties sectPr)
|
|
679
|
+
{
|
|
680
|
+
var headerPart = mainPart.AddNewPart<HeaderPart>();
|
|
681
|
+
|
|
682
|
+
var paragraph = new Paragraph(
|
|
683
|
+
new ParagraphProperties(
|
|
684
|
+
new ParagraphBorders(
|
|
685
|
+
new BottomBorder
|
|
686
|
+
{
|
|
687
|
+
Val = BorderValues.Single,
|
|
688
|
+
Size = 6, // 0.75pt line (in eighth-points)
|
|
689
|
+
Space = 1, // 1pt spacing between text and line
|
|
690
|
+
Color = "000000"
|
|
691
|
+
}),
|
|
692
|
+
new Justification { Val = JustificationValues.Center }),
|
|
693
|
+
new Run(
|
|
694
|
+
new RunProperties(
|
|
695
|
+
new Bold(),
|
|
696
|
+
new FontSize { Val = "20" }), // 10pt
|
|
697
|
+
new Text("Document Header")));
|
|
698
|
+
|
|
699
|
+
headerPart.Header = new Header(paragraph);
|
|
700
|
+
headerPart.Header.Save();
|
|
701
|
+
|
|
702
|
+
var headerRefId = mainPart.GetIdOfPart(headerPart);
|
|
703
|
+
sectPr.Append(new HeaderReference
|
|
704
|
+
{
|
|
705
|
+
Type = HeaderFooterValues.Default,
|
|
706
|
+
Id = headerRefId
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// ──────────────────────────────────────────────────────────────
|
|
711
|
+
// 11. ChangeHeaderPerSection — different headers per section
|
|
712
|
+
// ──────────────────────────────────────────────────────────────
|
|
713
|
+
/// <summary>
|
|
714
|
+
/// Creates a document with multiple sections, each having its own header.
|
|
715
|
+
///
|
|
716
|
+
/// In OOXML, sections are delimited by SectionProperties:
|
|
717
|
+
/// - Inner sections: sectPr inside a Paragraph's ParagraphProperties (section break)
|
|
718
|
+
/// - Last section: sectPr as direct child of Body
|
|
719
|
+
///
|
|
720
|
+
/// Each sectPr can reference different HeaderPart/FooterPart via its own
|
|
721
|
+
/// HeaderReference/FooterReference elements.
|
|
722
|
+
///
|
|
723
|
+
/// XML structure for multi-section document:
|
|
724
|
+
/// <w:body>
|
|
725
|
+
/// <!-- Section 1 content -->
|
|
726
|
+
/// <w:p><w:r><w:t>Section 1 content</w:t></w:r></w:p>
|
|
727
|
+
/// <w:p>
|
|
728
|
+
/// <w:pPr>
|
|
729
|
+
/// <w:sectPr> <!-- Section 1 break -->
|
|
730
|
+
/// <w:headerReference w:type="default" r:id="rId_hdr1"/>
|
|
731
|
+
/// <w:type w:val="nextPage"/>
|
|
732
|
+
/// </w:sectPr>
|
|
733
|
+
/// </w:pPr>
|
|
734
|
+
/// </w:p>
|
|
735
|
+
///
|
|
736
|
+
/// <!-- Section 2 content -->
|
|
737
|
+
/// <w:p><w:r><w:t>Section 2 content</w:t></w:r></w:p>
|
|
738
|
+
///
|
|
739
|
+
/// <!-- Final section properties (last child of body) -->
|
|
740
|
+
/// <w:sectPr>
|
|
741
|
+
/// <w:headerReference w:type="default" r:id="rId_hdr2"/>
|
|
742
|
+
/// </w:sectPr>
|
|
743
|
+
/// </w:body>
|
|
744
|
+
///
|
|
745
|
+
/// GOTCHA: A section break sectPr is placed inside a paragraph's ParagraphProperties.
|
|
746
|
+
/// The paragraph that contains the sectPr is the LAST paragraph of that section.
|
|
747
|
+
///
|
|
748
|
+
/// GOTCHA: If a section does not have its own HeaderReference, it inherits
|
|
749
|
+
/// the header from the previous section. To have NO header in a section,
|
|
750
|
+
/// you must explicitly link to an empty HeaderPart.
|
|
751
|
+
/// </summary>
|
|
752
|
+
public static void ChangeHeaderPerSection(MainDocumentPart mainPart, Body body)
|
|
753
|
+
{
|
|
754
|
+
// --- Create two different header parts ---
|
|
755
|
+
|
|
756
|
+
// Header for Section 1
|
|
757
|
+
var header1Part = mainPart.AddNewPart<HeaderPart>();
|
|
758
|
+
header1Part.Header = new Header(
|
|
759
|
+
new Paragraph(
|
|
760
|
+
new ParagraphProperties(
|
|
761
|
+
new Justification { Val = JustificationValues.Left }),
|
|
762
|
+
new Run(new Text("Section 1 — Introduction"))));
|
|
763
|
+
header1Part.Header.Save();
|
|
764
|
+
|
|
765
|
+
// Header for Section 2
|
|
766
|
+
var header2Part = mainPart.AddNewPart<HeaderPart>();
|
|
767
|
+
header2Part.Header = new Header(
|
|
768
|
+
new Paragraph(
|
|
769
|
+
new ParagraphProperties(
|
|
770
|
+
new Justification { Val = JustificationValues.Left }),
|
|
771
|
+
new Run(new Text("Section 2 — Analysis"))));
|
|
772
|
+
header2Part.Header.Save();
|
|
773
|
+
|
|
774
|
+
// --- Section 1 content ---
|
|
775
|
+
body.Append(new Paragraph(
|
|
776
|
+
new Run(new Text("This is content in Section 1."))));
|
|
777
|
+
body.Append(new Paragraph(
|
|
778
|
+
new Run(new Text("More Section 1 content..."))));
|
|
779
|
+
|
|
780
|
+
// --- Section 1 break: sectPr inside a paragraph's pPr ---
|
|
781
|
+
// This paragraph is the LAST paragraph of Section 1.
|
|
782
|
+
var sect1Pr = new SectionProperties(
|
|
783
|
+
new HeaderReference
|
|
784
|
+
{
|
|
785
|
+
Type = HeaderFooterValues.Default,
|
|
786
|
+
Id = mainPart.GetIdOfPart(header1Part)
|
|
787
|
+
},
|
|
788
|
+
// Section break type: start next section on a new page
|
|
789
|
+
new SectionType { Val = SectionMarkValues.NextPage });
|
|
790
|
+
|
|
791
|
+
// Page size and margins for section 1 (required for valid sectPr)
|
|
792
|
+
sect1Pr.Append(new DocumentFormat.OpenXml.Wordprocessing.PageSize
|
|
793
|
+
{
|
|
794
|
+
Width = (UInt32Value)12240U, // Letter width: 8.5" = 12240 DXA
|
|
795
|
+
Height = (UInt32Value)15840U // Letter height: 11" = 15840 DXA
|
|
796
|
+
});
|
|
797
|
+
sect1Pr.Append(new PageMargin
|
|
798
|
+
{
|
|
799
|
+
Top = 1440,
|
|
800
|
+
Bottom = 1440,
|
|
801
|
+
Left = (UInt32Value)1440U,
|
|
802
|
+
Right = (UInt32Value)1440U
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
// Wrap the sectPr in a paragraph's ParagraphProperties
|
|
806
|
+
var sectionBreakPara = new Paragraph(
|
|
807
|
+
new ParagraphProperties(sect1Pr));
|
|
808
|
+
body.Append(sectionBreakPara);
|
|
809
|
+
|
|
810
|
+
// --- Section 2 content ---
|
|
811
|
+
body.Append(new Paragraph(
|
|
812
|
+
new Run(new Text("This is content in Section 2."))));
|
|
813
|
+
body.Append(new Paragraph(
|
|
814
|
+
new Run(new Text("More Section 2 content..."))));
|
|
815
|
+
|
|
816
|
+
// --- Final section: sectPr as last child of Body ---
|
|
817
|
+
// This is the sectPr for the LAST section of the document.
|
|
818
|
+
var finalSectPr = new SectionProperties(
|
|
819
|
+
new HeaderReference
|
|
820
|
+
{
|
|
821
|
+
Type = HeaderFooterValues.Default,
|
|
822
|
+
Id = mainPart.GetIdOfPart(header2Part)
|
|
823
|
+
});
|
|
824
|
+
finalSectPr.Append(new DocumentFormat.OpenXml.Wordprocessing.PageSize
|
|
825
|
+
{
|
|
826
|
+
Width = (UInt32Value)12240U,
|
|
827
|
+
Height = (UInt32Value)15840U
|
|
828
|
+
});
|
|
829
|
+
finalSectPr.Append(new PageMargin
|
|
830
|
+
{
|
|
831
|
+
Top = 1440,
|
|
832
|
+
Bottom = 1440,
|
|
833
|
+
Left = (UInt32Value)1440U,
|
|
834
|
+
Right = (UInt32Value)1440U
|
|
835
|
+
});
|
|
836
|
+
body.Append(finalSectPr);
|
|
837
|
+
}
|
|
838
|
+
}
|