@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,1163 @@
|
|
|
1
|
+
using DocumentFormat.OpenXml;
|
|
2
|
+
using DocumentFormat.OpenXml.Wordprocessing;
|
|
3
|
+
|
|
4
|
+
namespace MiniMaxAIDocx.Core.Samples;
|
|
5
|
+
|
|
6
|
+
/// <summary>
|
|
7
|
+
/// Comprehensive reference for OpenXML table creation and formatting.
|
|
8
|
+
///
|
|
9
|
+
/// KEY GOTCHA: Every TableCell MUST contain at least one Paragraph, even if empty.
|
|
10
|
+
/// Omitting it produces a corrupt document that Word will attempt to repair.
|
|
11
|
+
///
|
|
12
|
+
/// Border size units: eighth-points (1/8 pt). Size="12" = 1.5pt line.
|
|
13
|
+
/// Width units: DXA (twentieths of a point). 1440 DXA = 1 inch.
|
|
14
|
+
/// Pct width: fiftieths of a percent. 5000 = 100%.
|
|
15
|
+
///
|
|
16
|
+
/// XML structure:
|
|
17
|
+
/// <w:tbl>
|
|
18
|
+
/// <w:tblPr> — table-level properties (width, alignment, borders, layout)
|
|
19
|
+
/// <w:tblGrid> — column definitions
|
|
20
|
+
/// <w:tr> — table row
|
|
21
|
+
/// <w:trPr> — row properties (height, header repeat)
|
|
22
|
+
/// <w:tc> — table cell
|
|
23
|
+
/// <w:tcPr> — cell properties (width, merge, shading, borders)
|
|
24
|
+
/// <w:p> — paragraph (REQUIRED, at least one)
|
|
25
|
+
/// </summary>
|
|
26
|
+
public static class TableSamples
|
|
27
|
+
{
|
|
28
|
+
// ──────────────────────────────────────────────────────────────
|
|
29
|
+
// 1. CreateSimpleTable — basic table with single-line borders
|
|
30
|
+
// ──────────────────────────────────────────────────────────────
|
|
31
|
+
/// <summary>
|
|
32
|
+
/// Creates a simple table with uniform single borders.
|
|
33
|
+
///
|
|
34
|
+
/// XML produced:
|
|
35
|
+
/// <w:tbl>
|
|
36
|
+
/// <w:tblPr>
|
|
37
|
+
/// <w:tblBorders>
|
|
38
|
+
/// <w:top w:val="single" w:sz="4" w:space="0" w:color="000000"/>
|
|
39
|
+
/// <w:left w:val="single" .../> <w:bottom .../> <w:right .../>
|
|
40
|
+
/// <w:insideH .../> <w:insideV .../>
|
|
41
|
+
/// </w:tblBorders>
|
|
42
|
+
/// <w:tblW w:w="5000" w:type="pct"/>
|
|
43
|
+
/// </w:tblPr>
|
|
44
|
+
/// <w:tblGrid> <w:gridCol w:w="..."/> ... </w:tblGrid>
|
|
45
|
+
/// <w:tr> <w:tc> <w:p><w:r><w:t>Header1</w:t></w:r></w:p> </w:tc> ... </w:tr>
|
|
46
|
+
/// ...
|
|
47
|
+
/// </w:tbl>
|
|
48
|
+
/// </summary>
|
|
49
|
+
/// <param name="body">The document body to append the table to.</param>
|
|
50
|
+
/// <param name="headers">Column header strings.</param>
|
|
51
|
+
/// <param name="data">Rows of data; each inner array matches headers length.</param>
|
|
52
|
+
public static Table CreateSimpleTable(Body body, string[] headers, string[][] data)
|
|
53
|
+
{
|
|
54
|
+
var table = new Table();
|
|
55
|
+
|
|
56
|
+
// -- Table Properties --
|
|
57
|
+
var tblPr = new TableProperties();
|
|
58
|
+
|
|
59
|
+
// Full-width table: Pct 5000 = 100%
|
|
60
|
+
tblPr.Append(new TableWidth { Width = "5000", Type = TableWidthUnitValues.Pct });
|
|
61
|
+
|
|
62
|
+
// Single borders all around + inside gridlines
|
|
63
|
+
// Border Size is in eighth-points: 4 = 0.5pt (thin), 12 = 1.5pt, 24 = 3pt
|
|
64
|
+
var borders = new TableBorders(
|
|
65
|
+
new TopBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
66
|
+
new LeftBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
67
|
+
new BottomBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
68
|
+
new RightBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
69
|
+
new InsideHorizontalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
70
|
+
new InsideVerticalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" }
|
|
71
|
+
);
|
|
72
|
+
tblPr.Append(borders);
|
|
73
|
+
table.Append(tblPr);
|
|
74
|
+
|
|
75
|
+
// -- Table Grid: equal column widths --
|
|
76
|
+
// Grid columns define the default width in DXA.
|
|
77
|
+
// Total page width ~9360 DXA for letter with 1" margins (8.5" - 2" = 6.5" = 9360 DXA)
|
|
78
|
+
var grid = new TableGrid();
|
|
79
|
+
int colWidth = 9360 / headers.Length;
|
|
80
|
+
foreach (var _ in headers)
|
|
81
|
+
{
|
|
82
|
+
grid.Append(new GridColumn { Width = colWidth.ToString() });
|
|
83
|
+
}
|
|
84
|
+
table.Append(grid);
|
|
85
|
+
|
|
86
|
+
// -- Header Row --
|
|
87
|
+
var headerRow = new TableRow();
|
|
88
|
+
foreach (var h in headers)
|
|
89
|
+
{
|
|
90
|
+
var cell = new TableCell();
|
|
91
|
+
// GOTCHA: every cell MUST have at least one Paragraph
|
|
92
|
+
cell.Append(new Paragraph(
|
|
93
|
+
new Run(
|
|
94
|
+
new RunProperties(new Bold()),
|
|
95
|
+
new Text(h) { Space = SpaceProcessingModeValues.Preserve })));
|
|
96
|
+
headerRow.Append(cell);
|
|
97
|
+
}
|
|
98
|
+
table.Append(headerRow);
|
|
99
|
+
|
|
100
|
+
// -- Data Rows --
|
|
101
|
+
foreach (var rowData in data)
|
|
102
|
+
{
|
|
103
|
+
var row = new TableRow();
|
|
104
|
+
foreach (var cellText in rowData)
|
|
105
|
+
{
|
|
106
|
+
var cell = new TableCell();
|
|
107
|
+
cell.Append(new Paragraph(
|
|
108
|
+
new Run(new Text(cellText) { Space = SpaceProcessingModeValues.Preserve })));
|
|
109
|
+
row.Append(cell);
|
|
110
|
+
}
|
|
111
|
+
table.Append(row);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
body.Append(table);
|
|
115
|
+
// Add an empty paragraph after the table (Word best practice)
|
|
116
|
+
body.Append(new Paragraph());
|
|
117
|
+
return table;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ──────────────────────────────────────────────────────────────
|
|
121
|
+
// 2. CreateStyledTable — header shading, zebra striping, totals
|
|
122
|
+
// ──────────────────────────────────────────────────────────────
|
|
123
|
+
/// <summary>
|
|
124
|
+
/// Creates a professionally styled table with:
|
|
125
|
+
/// - Dark header row (navy background, white bold text)
|
|
126
|
+
/// - Alternating row shading (zebra striping)
|
|
127
|
+
/// - Bold totals row at the bottom
|
|
128
|
+
///
|
|
129
|
+
/// XML for shaded cell:
|
|
130
|
+
/// <w:tc>
|
|
131
|
+
/// <w:tcPr>
|
|
132
|
+
/// <w:shd w:val="clear" w:color="auto" w:fill="1F3864"/>
|
|
133
|
+
/// </w:tcPr>
|
|
134
|
+
/// <w:p>
|
|
135
|
+
/// <w:pPr><w:jc w:val="center"/></w:pPr>
|
|
136
|
+
/// <w:r>
|
|
137
|
+
/// <w:rPr><w:b/><w:color w:val="FFFFFF"/></w:rPr>
|
|
138
|
+
/// <w:t>Header</w:t>
|
|
139
|
+
/// </w:r>
|
|
140
|
+
/// </w:p>
|
|
141
|
+
/// </w:tc>
|
|
142
|
+
/// </summary>
|
|
143
|
+
public static Table CreateStyledTable(Body body)
|
|
144
|
+
{
|
|
145
|
+
var table = new Table();
|
|
146
|
+
|
|
147
|
+
// Table properties: full width, single borders
|
|
148
|
+
var tblPr = new TableProperties(
|
|
149
|
+
new TableWidth { Width = "5000", Type = TableWidthUnitValues.Pct },
|
|
150
|
+
new TableBorders(
|
|
151
|
+
new TopBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "1F3864" },
|
|
152
|
+
new LeftBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "1F3864" },
|
|
153
|
+
new BottomBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "1F3864" },
|
|
154
|
+
new RightBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "1F3864" },
|
|
155
|
+
new InsideHorizontalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "1F3864" },
|
|
156
|
+
new InsideVerticalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "1F3864" }
|
|
157
|
+
));
|
|
158
|
+
table.Append(tblPr);
|
|
159
|
+
|
|
160
|
+
// Grid: 3 columns
|
|
161
|
+
var grid = new TableGrid(
|
|
162
|
+
new GridColumn { Width = "3120" },
|
|
163
|
+
new GridColumn { Width = "3120" },
|
|
164
|
+
new GridColumn { Width = "3120" });
|
|
165
|
+
table.Append(grid);
|
|
166
|
+
|
|
167
|
+
string[] headers = ["Item", "Quantity", "Price"];
|
|
168
|
+
string[][] data =
|
|
169
|
+
[
|
|
170
|
+
["Widget A", "10", "$5.00"],
|
|
171
|
+
["Widget B", "25", "$3.50"],
|
|
172
|
+
["Widget C", "15", "$7.25"],
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
// -- Header row: dark navy background, white bold text --
|
|
176
|
+
var headerRow = new TableRow();
|
|
177
|
+
foreach (var h in headers)
|
|
178
|
+
{
|
|
179
|
+
var cell = new TableCell(
|
|
180
|
+
new TableCellProperties(
|
|
181
|
+
new Shading
|
|
182
|
+
{
|
|
183
|
+
Val = ShadingPatternValues.Clear,
|
|
184
|
+
Color = "auto",
|
|
185
|
+
Fill = "1F3864" // Dark navy
|
|
186
|
+
}),
|
|
187
|
+
new Paragraph(
|
|
188
|
+
new ParagraphProperties(
|
|
189
|
+
new Justification { Val = JustificationValues.Center }),
|
|
190
|
+
new Run(
|
|
191
|
+
new RunProperties(
|
|
192
|
+
new Bold(),
|
|
193
|
+
new Color { Val = "FFFFFF" }), // White text
|
|
194
|
+
new Text(h))));
|
|
195
|
+
headerRow.Append(cell);
|
|
196
|
+
}
|
|
197
|
+
table.Append(headerRow);
|
|
198
|
+
|
|
199
|
+
// -- Data rows with zebra striping --
|
|
200
|
+
for (int i = 0; i < data.Length; i++)
|
|
201
|
+
{
|
|
202
|
+
var row = new TableRow();
|
|
203
|
+
// Alternate rows get light gray background
|
|
204
|
+
string? fillColor = (i % 2 == 1) ? "D9E2F3" : null;
|
|
205
|
+
|
|
206
|
+
foreach (var cellText in data[i])
|
|
207
|
+
{
|
|
208
|
+
var tcPr = new TableCellProperties();
|
|
209
|
+
if (fillColor != null)
|
|
210
|
+
{
|
|
211
|
+
tcPr.Append(new Shading
|
|
212
|
+
{
|
|
213
|
+
Val = ShadingPatternValues.Clear,
|
|
214
|
+
Color = "auto",
|
|
215
|
+
Fill = fillColor
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
var cell = new TableCell(
|
|
219
|
+
tcPr,
|
|
220
|
+
new Paragraph(
|
|
221
|
+
new Run(new Text(cellText) { Space = SpaceProcessingModeValues.Preserve })));
|
|
222
|
+
row.Append(cell);
|
|
223
|
+
}
|
|
224
|
+
table.Append(row);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// -- Totals row: bold text, top border emphasis --
|
|
228
|
+
var totalsRow = new TableRow();
|
|
229
|
+
string[] totals = ["Total", "50", "$257.50"];
|
|
230
|
+
foreach (var t in totals)
|
|
231
|
+
{
|
|
232
|
+
var cell = new TableCell(
|
|
233
|
+
new TableCellProperties(
|
|
234
|
+
new Shading
|
|
235
|
+
{
|
|
236
|
+
Val = ShadingPatternValues.Clear,
|
|
237
|
+
Color = "auto",
|
|
238
|
+
Fill = "1F3864"
|
|
239
|
+
}),
|
|
240
|
+
new Paragraph(
|
|
241
|
+
new Run(
|
|
242
|
+
new RunProperties(
|
|
243
|
+
new Bold(),
|
|
244
|
+
new Color { Val = "FFFFFF" }),
|
|
245
|
+
new Text(t) { Space = SpaceProcessingModeValues.Preserve })));
|
|
246
|
+
totalsRow.Append(cell);
|
|
247
|
+
}
|
|
248
|
+
table.Append(totalsRow);
|
|
249
|
+
|
|
250
|
+
body.Append(table);
|
|
251
|
+
body.Append(new Paragraph());
|
|
252
|
+
return table;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ──────────────────────────────────────────────────────────────
|
|
256
|
+
// 3. CreateThreeLineTable — academic 三线表
|
|
257
|
+
// ──────────────────────────────────────────────────────────────
|
|
258
|
+
/// <summary>
|
|
259
|
+
/// Creates an academic three-line table (三线表):
|
|
260
|
+
/// - Thick top border (1.5pt = Size 12)
|
|
261
|
+
/// - Thin border below header row (0.75pt = Size 6)
|
|
262
|
+
/// - Thick bottom border (1.5pt = Size 12)
|
|
263
|
+
/// - NO vertical borders, NO inside vertical borders
|
|
264
|
+
/// - NO left/right borders
|
|
265
|
+
///
|
|
266
|
+
/// This is the standard table style for Chinese academic papers (GB/T 7713).
|
|
267
|
+
///
|
|
268
|
+
/// XML produced:
|
|
269
|
+
/// <w:tbl>
|
|
270
|
+
/// <w:tblPr>
|
|
271
|
+
/// <w:tblBorders>
|
|
272
|
+
/// <w:top w:val="single" w:sz="12" w:space="0" w:color="000000"/>
|
|
273
|
+
/// <w:bottom w:val="single" w:sz="12" w:space="0" w:color="000000"/>
|
|
274
|
+
/// <!-- No left, right, insideV borders -->
|
|
275
|
+
/// <w:insideH w:val="none" w:sz="0" w:space="0" w:color="auto"/>
|
|
276
|
+
/// <w:insideV w:val="none" w:sz="0" w:space="0" w:color="auto"/>
|
|
277
|
+
/// </w:tblBorders>
|
|
278
|
+
/// </w:tblPr>
|
|
279
|
+
/// ...
|
|
280
|
+
/// <!-- Header row uses per-cell bottom border for the thin line -->
|
|
281
|
+
/// </w:tbl>
|
|
282
|
+
/// </summary>
|
|
283
|
+
public static Table CreateThreeLineTable(Body body)
|
|
284
|
+
{
|
|
285
|
+
var table = new Table();
|
|
286
|
+
|
|
287
|
+
// Table borders: only top and bottom (thick), no sides, no inside
|
|
288
|
+
var tblPr = new TableProperties(
|
|
289
|
+
new TableWidth { Width = "5000", Type = TableWidthUnitValues.Pct },
|
|
290
|
+
new TableBorders(
|
|
291
|
+
new TopBorder { Val = BorderValues.Single, Size = 12, Space = 0, Color = "000000" },
|
|
292
|
+
new BottomBorder { Val = BorderValues.Single, Size = 12, Space = 0, Color = "000000" },
|
|
293
|
+
// Explicitly set left/right/insideH/insideV to none
|
|
294
|
+
new LeftBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
295
|
+
new RightBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
296
|
+
new InsideHorizontalBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
297
|
+
new InsideVerticalBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" }
|
|
298
|
+
));
|
|
299
|
+
table.Append(tblPr);
|
|
300
|
+
|
|
301
|
+
var grid = new TableGrid(
|
|
302
|
+
new GridColumn { Width = "3120" },
|
|
303
|
+
new GridColumn { Width = "3120" },
|
|
304
|
+
new GridColumn { Width = "3120" });
|
|
305
|
+
table.Append(grid);
|
|
306
|
+
|
|
307
|
+
string[] headers = ["Variable", "Mean", "SD"];
|
|
308
|
+
|
|
309
|
+
// -- Header row: centered, bold, with thin bottom border on each cell --
|
|
310
|
+
var headerRow = new TableRow();
|
|
311
|
+
foreach (var h in headers)
|
|
312
|
+
{
|
|
313
|
+
// Per-cell bottom border creates the thin "second line" of the three-line table
|
|
314
|
+
var tcPr = new TableCellProperties(
|
|
315
|
+
new TableCellBorders(
|
|
316
|
+
new BottomBorder { Val = BorderValues.Single, Size = 6, Space = 0, Color = "000000" }
|
|
317
|
+
));
|
|
318
|
+
|
|
319
|
+
var cell = new TableCell(
|
|
320
|
+
tcPr,
|
|
321
|
+
new Paragraph(
|
|
322
|
+
new ParagraphProperties(
|
|
323
|
+
new Justification { Val = JustificationValues.Center }),
|
|
324
|
+
new Run(
|
|
325
|
+
new RunProperties(new Bold()),
|
|
326
|
+
new Text(h))));
|
|
327
|
+
headerRow.Append(cell);
|
|
328
|
+
}
|
|
329
|
+
table.Append(headerRow);
|
|
330
|
+
|
|
331
|
+
// -- Data rows: centered text, no borders --
|
|
332
|
+
string[][] data =
|
|
333
|
+
[
|
|
334
|
+
["Age", "25.3", "4.2"],
|
|
335
|
+
["Height", "170.5", "8.1"],
|
|
336
|
+
["Weight", "65.2", "10.3"],
|
|
337
|
+
];
|
|
338
|
+
foreach (var rowData in data)
|
|
339
|
+
{
|
|
340
|
+
var row = new TableRow();
|
|
341
|
+
foreach (var cellText in rowData)
|
|
342
|
+
{
|
|
343
|
+
var cell = new TableCell(
|
|
344
|
+
new Paragraph(
|
|
345
|
+
new ParagraphProperties(
|
|
346
|
+
new Justification { Val = JustificationValues.Center }),
|
|
347
|
+
new Run(new Text(cellText))));
|
|
348
|
+
row.Append(cell);
|
|
349
|
+
}
|
|
350
|
+
table.Append(row);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
body.Append(table);
|
|
354
|
+
body.Append(new Paragraph());
|
|
355
|
+
return table;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ──────────────────────────────────────────────────────────────
|
|
359
|
+
// 4. CreateBorderedTable — multiple border styles
|
|
360
|
+
// ──────────────────────────────────────────────────────────────
|
|
361
|
+
/// <summary>
|
|
362
|
+
/// Creates a table demonstrating different border styles.
|
|
363
|
+
///
|
|
364
|
+
/// Border Val options:
|
|
365
|
+
/// BorderValues.Single — normal single line
|
|
366
|
+
/// BorderValues.Double — double line
|
|
367
|
+
/// BorderValues.Thick — thick single line
|
|
368
|
+
/// BorderValues.Dashed — dashed line
|
|
369
|
+
/// BorderValues.DashSmallGap — dashed with small gaps
|
|
370
|
+
/// BorderValues.DotDash — dot-dash pattern
|
|
371
|
+
/// BorderValues.Dotted — dotted line
|
|
372
|
+
/// BorderValues.Wave — wavy line
|
|
373
|
+
/// BorderValues.None — no border
|
|
374
|
+
///
|
|
375
|
+
/// Size is in eighth-points: 4 = 0.5pt, 8 = 1pt, 12 = 1.5pt, 24 = 3pt
|
|
376
|
+
/// </summary>
|
|
377
|
+
public static Table CreateBorderedTable(Body body)
|
|
378
|
+
{
|
|
379
|
+
var table = new Table();
|
|
380
|
+
|
|
381
|
+
// Use different border styles on each side to demonstrate the options
|
|
382
|
+
var tblPr = new TableProperties(
|
|
383
|
+
new TableWidth { Width = "5000", Type = TableWidthUnitValues.Pct },
|
|
384
|
+
new TableBorders(
|
|
385
|
+
new TopBorder { Val = BorderValues.Double, Size = 4, Space = 0, Color = "000000" },
|
|
386
|
+
new BottomBorder { Val = BorderValues.Double, Size = 4, Space = 0, Color = "000000" },
|
|
387
|
+
new LeftBorder { Val = BorderValues.Thick, Size = 12, Space = 0, Color = "333333" },
|
|
388
|
+
new RightBorder { Val = BorderValues.Thick, Size = 12, Space = 0, Color = "333333" },
|
|
389
|
+
new InsideHorizontalBorder { Val = BorderValues.Dashed, Size = 4, Space = 0, Color = "999999" },
|
|
390
|
+
new InsideVerticalBorder { Val = BorderValues.Dotted, Size = 4, Space = 0, Color = "999999" }
|
|
391
|
+
));
|
|
392
|
+
table.Append(tblPr);
|
|
393
|
+
|
|
394
|
+
var grid = new TableGrid(
|
|
395
|
+
new GridColumn { Width = "4680" },
|
|
396
|
+
new GridColumn { Width = "4680" });
|
|
397
|
+
table.Append(grid);
|
|
398
|
+
|
|
399
|
+
// Sample data
|
|
400
|
+
string[][] rows =
|
|
401
|
+
[
|
|
402
|
+
["Double top / Thick sides", "Dotted vertical inside"],
|
|
403
|
+
["Dashed horizontal inside", "Double bottom"],
|
|
404
|
+
];
|
|
405
|
+
foreach (var rowData in rows)
|
|
406
|
+
{
|
|
407
|
+
var row = new TableRow();
|
|
408
|
+
foreach (var cellText in rowData)
|
|
409
|
+
{
|
|
410
|
+
var cell = new TableCell(
|
|
411
|
+
new Paragraph(new Run(new Text(cellText))));
|
|
412
|
+
row.Append(cell);
|
|
413
|
+
}
|
|
414
|
+
table.Append(row);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
body.Append(table);
|
|
418
|
+
body.Append(new Paragraph());
|
|
419
|
+
return table;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// ──────────────────────────────────────────────────────────────
|
|
423
|
+
// 5. SetTableWidth — Pct, DXA, Auto
|
|
424
|
+
// ──────────────────────────────────────────────────────────────
|
|
425
|
+
/// <summary>
|
|
426
|
+
/// Demonstrates three table width modes:
|
|
427
|
+
///
|
|
428
|
+
/// 1. Pct (percentage): Value in fiftieths of a percent. 5000 = 100%, 2500 = 50%.
|
|
429
|
+
/// XML: <w:tblW w:w="5000" w:type="pct"/>
|
|
430
|
+
///
|
|
431
|
+
/// 2. Dxa (absolute): Value in twentieths of a point. 1440 = 1 inch, 9360 = 6.5 inches.
|
|
432
|
+
/// XML: <w:tblW w:w="9360" w:type="dxa"/>
|
|
433
|
+
///
|
|
434
|
+
/// 3. Auto: Word determines width from content.
|
|
435
|
+
/// XML: <w:tblW w:w="0" w:type="auto"/>
|
|
436
|
+
/// </summary>
|
|
437
|
+
public static void SetTableWidth(Table table)
|
|
438
|
+
{
|
|
439
|
+
var tblPr = table.GetFirstChild<TableProperties>()
|
|
440
|
+
?? table.PrependChild(new TableProperties());
|
|
441
|
+
|
|
442
|
+
// --- Option A: Percentage width (100%) ---
|
|
443
|
+
// Pct value is in fiftieths of a percent: 5000 = 100%
|
|
444
|
+
tblPr.TableWidth = new TableWidth
|
|
445
|
+
{
|
|
446
|
+
Width = "5000",
|
|
447
|
+
Type = TableWidthUnitValues.Pct
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
// --- Option B: Absolute width (6.5 inches = 9360 DXA) ---
|
|
451
|
+
// tblPr.TableWidth = new TableWidth
|
|
452
|
+
// {
|
|
453
|
+
// Width = "9360", // 6.5 * 1440 = 9360 DXA
|
|
454
|
+
// Type = TableWidthUnitValues.Dxa
|
|
455
|
+
// };
|
|
456
|
+
|
|
457
|
+
// --- Option C: Auto width ---
|
|
458
|
+
// tblPr.TableWidth = new TableWidth
|
|
459
|
+
// {
|
|
460
|
+
// Width = "0",
|
|
461
|
+
// Type = TableWidthUnitValues.Auto
|
|
462
|
+
// };
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// ──────────────────────────────────────────────────────────────
|
|
466
|
+
// 6. SetTableLayout — Fixed vs AutoFit
|
|
467
|
+
// ──────────────────────────────────────────────────────────────
|
|
468
|
+
/// <summary>
|
|
469
|
+
/// Controls whether the table uses fixed column widths or auto-fits to content.
|
|
470
|
+
///
|
|
471
|
+
/// Fixed layout: columns keep their exact width from TableGrid; content wraps.
|
|
472
|
+
/// XML: <w:tblLayout w:type="fixed"/>
|
|
473
|
+
///
|
|
474
|
+
/// AutoFit layout: Word adjusts column widths based on content. This is the default.
|
|
475
|
+
/// XML: <w:tblLayout w:type="autofit"/>
|
|
476
|
+
///
|
|
477
|
+
/// GOTCHA: Fixed layout is required for predictable column widths; AutoFit
|
|
478
|
+
/// may override your GridColumn values.
|
|
479
|
+
/// </summary>
|
|
480
|
+
public static void SetTableLayout(Table table)
|
|
481
|
+
{
|
|
482
|
+
var tblPr = table.GetFirstChild<TableProperties>()
|
|
483
|
+
?? table.PrependChild(new TableProperties());
|
|
484
|
+
|
|
485
|
+
// Fixed layout — columns respect GridColumn widths exactly
|
|
486
|
+
tblPr.TableLayout = new TableLayout
|
|
487
|
+
{
|
|
488
|
+
Type = TableLayoutValues.Fixed
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// AutoFit layout (default) — Word adjusts widths to content
|
|
492
|
+
// tblPr.TableLayout = new TableLayout
|
|
493
|
+
// {
|
|
494
|
+
// Type = TableLayoutValues.Autofit
|
|
495
|
+
// };
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// ──────────────────────────────────────────────────────────────
|
|
499
|
+
// 7. SetTableAlignment — center, right, left with indent
|
|
500
|
+
// ──────────────────────────────────────────────────────────────
|
|
501
|
+
/// <summary>
|
|
502
|
+
/// Controls horizontal alignment of the table on the page.
|
|
503
|
+
///
|
|
504
|
+
/// XML: <w:jc w:val="center"/>
|
|
505
|
+
///
|
|
506
|
+
/// For left alignment with indent:
|
|
507
|
+
/// XML: <w:tblInd w:w="720" w:type="dxa"/>
|
|
508
|
+
///
|
|
509
|
+
/// GOTCHA: TableJustification (w:jc) inside tblPr is DIFFERENT from paragraph Justification.
|
|
510
|
+
/// </summary>
|
|
511
|
+
public static void SetTableAlignment(Table table)
|
|
512
|
+
{
|
|
513
|
+
var tblPr = table.GetFirstChild<TableProperties>()
|
|
514
|
+
?? table.PrependChild(new TableProperties());
|
|
515
|
+
|
|
516
|
+
// --- Option A: Center the table ---
|
|
517
|
+
tblPr.TableJustification = new TableJustification
|
|
518
|
+
{
|
|
519
|
+
Val = TableRowAlignmentValues.Center
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
// --- Option B: Right-align ---
|
|
523
|
+
// tblPr.TableJustification = new TableJustification
|
|
524
|
+
// {
|
|
525
|
+
// Val = TableRowAlignmentValues.Right
|
|
526
|
+
// };
|
|
527
|
+
|
|
528
|
+
// --- Option C: Left with indent (0.5 inch = 720 DXA) ---
|
|
529
|
+
// tblPr.TableJustification = new TableJustification
|
|
530
|
+
// {
|
|
531
|
+
// Val = TableRowAlignmentValues.Left
|
|
532
|
+
// };
|
|
533
|
+
// tblPr.TableIndentation = new TableIndentation
|
|
534
|
+
// {
|
|
535
|
+
// Width = 720,
|
|
536
|
+
// Type = TableWidthUnitValues.Dxa
|
|
537
|
+
// };
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// ──────────────────────────────────────────────────────────────
|
|
541
|
+
// 8. ConfigureTableGrid — column widths
|
|
542
|
+
// ──────────────────────────────────────────────────────────────
|
|
543
|
+
/// <summary>
|
|
544
|
+
/// Sets explicit column widths via TableGrid / GridColumn elements.
|
|
545
|
+
///
|
|
546
|
+
/// GridColumn.Width is in DXA (twentieths of a point).
|
|
547
|
+
/// 1440 DXA = 1 inch. Common page width = 9360 DXA (6.5" printable on letter).
|
|
548
|
+
///
|
|
549
|
+
/// XML:
|
|
550
|
+
/// <w:tblGrid>
|
|
551
|
+
/// <w:gridCol w:w="1440"/> <!-- 1 inch -->
|
|
552
|
+
/// <w:gridCol w:w="4680"/> <!-- 3.25 inches -->
|
|
553
|
+
/// <w:gridCol w:w="3240"/> <!-- 2.25 inches -->
|
|
554
|
+
/// </w:tblGrid>
|
|
555
|
+
///
|
|
556
|
+
/// GOTCHA: The number of GridColumn elements should match the maximum number
|
|
557
|
+
/// of cells in any row (before merging). Merged cells still correspond to
|
|
558
|
+
/// multiple grid columns via GridSpan.
|
|
559
|
+
/// </summary>
|
|
560
|
+
public static void ConfigureTableGrid(Table table)
|
|
561
|
+
{
|
|
562
|
+
// Remove existing grid if present
|
|
563
|
+
var existingGrid = table.GetFirstChild<TableGrid>();
|
|
564
|
+
existingGrid?.Remove();
|
|
565
|
+
|
|
566
|
+
// 3 columns: narrow (1"), wide (3.25"), medium (2.25") = 6.5" total
|
|
567
|
+
var grid = new TableGrid(
|
|
568
|
+
new GridColumn { Width = "1440" }, // 1 inch
|
|
569
|
+
new GridColumn { Width = "4680" }, // 3.25 inches
|
|
570
|
+
new GridColumn { Width = "3240" } // 2.25 inches
|
|
571
|
+
);
|
|
572
|
+
|
|
573
|
+
// Grid must come after TableProperties, before any TableRow
|
|
574
|
+
var tblPr = table.GetFirstChild<TableProperties>();
|
|
575
|
+
if (tblPr != null)
|
|
576
|
+
tblPr.InsertAfterSelf(grid);
|
|
577
|
+
else
|
|
578
|
+
table.PrependChild(grid);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// ──────────────────────────────────────────────────────────────
|
|
582
|
+
// 9. SetCellProperties — width, vAlign, text direction, no-wrap, shading
|
|
583
|
+
// ──────────────────────────────────────────────────────────────
|
|
584
|
+
/// <summary>
|
|
585
|
+
/// Demonstrates the key TableCellProperties settings.
|
|
586
|
+
///
|
|
587
|
+
/// XML:
|
|
588
|
+
/// <w:tcPr>
|
|
589
|
+
/// <w:tcW w:w="2880" w:type="dxa"/>
|
|
590
|
+
/// <w:vAlign w:val="center"/>
|
|
591
|
+
/// <w:textDirection w:val="btLr"/>
|
|
592
|
+
/// <w:noWrap/>
|
|
593
|
+
/// <w:shd w:val="clear" w:color="auto" w:fill="E2EFDA"/>
|
|
594
|
+
/// </w:tcPr>
|
|
595
|
+
///
|
|
596
|
+
/// Vertical alignment values:
|
|
597
|
+
/// TableVerticalAlignmentValues.Top — default
|
|
598
|
+
/// TableVerticalAlignmentValues.Center — vertically centered
|
|
599
|
+
/// TableVerticalAlignmentValues.Bottom — bottom-aligned
|
|
600
|
+
///
|
|
601
|
+
/// Text direction values:
|
|
602
|
+
/// TextDirectionValues.LefToRightTopToBottom — normal horizontal (default)
|
|
603
|
+
/// TextDirectionValues.TopToBottomRightToLeft — vertical (CJK style)
|
|
604
|
+
/// TextDirectionValues.BottomToTopLeftToRight — rotated 90 CCW
|
|
605
|
+
/// </summary>
|
|
606
|
+
public static void SetCellProperties(TableCell cell)
|
|
607
|
+
{
|
|
608
|
+
var tcPr = cell.GetFirstChild<TableCellProperties>()
|
|
609
|
+
?? cell.PrependChild(new TableCellProperties());
|
|
610
|
+
|
|
611
|
+
// Cell width: 2 inches = 2880 DXA
|
|
612
|
+
tcPr.TableCellWidth = new TableCellWidth
|
|
613
|
+
{
|
|
614
|
+
Width = "2880",
|
|
615
|
+
Type = TableWidthUnitValues.Dxa
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
// Vertical alignment: center content vertically in cell
|
|
619
|
+
tcPr.TableCellVerticalAlignment = new TableCellVerticalAlignment
|
|
620
|
+
{
|
|
621
|
+
Val = TableVerticalAlignmentValues.Center
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
// Text direction: bottom-to-top (rotated 90 degrees counterclockwise)
|
|
625
|
+
// Useful for narrow column headers
|
|
626
|
+
tcPr.TextDirection = new TextDirection
|
|
627
|
+
{
|
|
628
|
+
Val = TextDirectionValues.BottomToTopLeftToRight
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
// No-wrap: prevent text wrapping, force cell to expand horizontally
|
|
632
|
+
tcPr.NoWrap = new NoWrap();
|
|
633
|
+
|
|
634
|
+
// Shading (background color): light green
|
|
635
|
+
// Fill is the background color; Color is the pattern color (usually "auto")
|
|
636
|
+
tcPr.Shading = new Shading
|
|
637
|
+
{
|
|
638
|
+
Val = ShadingPatternValues.Clear,
|
|
639
|
+
Color = "auto",
|
|
640
|
+
Fill = "E2EFDA"
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// ──────────────────────────────────────────────────────────────
|
|
645
|
+
// 10. SetTableCellMargins — table-level default cell margins
|
|
646
|
+
// ──────────────────────────────────────────────────────────────
|
|
647
|
+
/// <summary>
|
|
648
|
+
/// Sets default cell margins (padding) for the entire table.
|
|
649
|
+
/// These apply to ALL cells unless overridden per-cell.
|
|
650
|
+
///
|
|
651
|
+
/// XML:
|
|
652
|
+
/// <w:tblPr>
|
|
653
|
+
/// <w:tblCellMar>
|
|
654
|
+
/// <w:top w:w="72" w:type="dxa"/>
|
|
655
|
+
/// <w:start w:w="115" w:type="dxa"/>
|
|
656
|
+
/// <w:bottom w:w="72" w:type="dxa"/>
|
|
657
|
+
/// <w:end w:w="115" w:type="dxa"/>
|
|
658
|
+
/// </w:tblCellMar>
|
|
659
|
+
/// </w:tblPr>
|
|
660
|
+
///
|
|
661
|
+
/// Units: DXA. Default Word margins are approximately top/bottom=0, left/right=108 DXA.
|
|
662
|
+
///
|
|
663
|
+
/// GOTCHA: Use StartMargin/EndMargin (not LeftMargin/RightMargin) for OOXML Strict
|
|
664
|
+
/// compliance, but Word also accepts Left/Right.
|
|
665
|
+
/// </summary>
|
|
666
|
+
public static void SetTableCellMargins(Table table)
|
|
667
|
+
{
|
|
668
|
+
var tblPr = table.GetFirstChild<TableProperties>()
|
|
669
|
+
?? table.PrependChild(new TableProperties());
|
|
670
|
+
|
|
671
|
+
tblPr.TableCellMarginDefault = new TableCellMarginDefault(
|
|
672
|
+
new TopMargin { Width = "72", Type = TableWidthUnitValues.Dxa }, // ~0.05 inch
|
|
673
|
+
new StartMargin { Width = "115", Type = TableWidthUnitValues.Dxa }, // ~0.08 inch
|
|
674
|
+
new BottomMargin { Width = "72", Type = TableWidthUnitValues.Dxa },
|
|
675
|
+
new EndMargin { Width = "115", Type = TableWidthUnitValues.Dxa }
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// ──────────────────────────────────────────────────────────────
|
|
680
|
+
// 11. SetPerCellMargins — per-cell override
|
|
681
|
+
// ──────────────────────────────────────────────────────────────
|
|
682
|
+
/// <summary>
|
|
683
|
+
/// Overrides the table-level cell margins for a specific cell.
|
|
684
|
+
///
|
|
685
|
+
/// XML:
|
|
686
|
+
/// <w:tcPr>
|
|
687
|
+
/// <w:tcMar>
|
|
688
|
+
/// <w:top w:w="144" w:type="dxa"/>
|
|
689
|
+
/// <w:start w:w="216" w:type="dxa"/>
|
|
690
|
+
/// <w:bottom w:w="144" w:type="dxa"/>
|
|
691
|
+
/// <w:end w:w="216" w:type="dxa"/>
|
|
692
|
+
/// </w:tcMar>
|
|
693
|
+
/// </w:tcPr>
|
|
694
|
+
///
|
|
695
|
+
/// GOTCHA: Per-cell margins fully replace the table defaults for that cell.
|
|
696
|
+
/// You must specify all four sides; omitted sides get zero margin (not the table default).
|
|
697
|
+
/// </summary>
|
|
698
|
+
public static void SetPerCellMargins(TableCell cell)
|
|
699
|
+
{
|
|
700
|
+
var tcPr = cell.GetFirstChild<TableCellProperties>()
|
|
701
|
+
?? cell.PrependChild(new TableCellProperties());
|
|
702
|
+
|
|
703
|
+
tcPr.TableCellMargin = new TableCellMargin(
|
|
704
|
+
new TopMargin { Width = "144", Type = TableWidthUnitValues.Dxa }, // 0.1 inch
|
|
705
|
+
new StartMargin { Width = "216", Type = TableWidthUnitValues.Dxa }, // 0.15 inch
|
|
706
|
+
new BottomMargin { Width = "144", Type = TableWidthUnitValues.Dxa },
|
|
707
|
+
new EndMargin { Width = "216", Type = TableWidthUnitValues.Dxa }
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// ──────────────────────────────────────────────────────────────
|
|
712
|
+
// 12. SetRowHeight — exact, atLeast, auto
|
|
713
|
+
// ──────────────────────────────────────────────────────────────
|
|
714
|
+
/// <summary>
|
|
715
|
+
/// Controls the height of a table row.
|
|
716
|
+
///
|
|
717
|
+
/// XML: <w:trPr><w:trHeight w:val="720" w:hRule="exact"/></w:trPr>
|
|
718
|
+
///
|
|
719
|
+
/// Height rule values:
|
|
720
|
+
/// HeightRuleValues.Exact — row is exactly the specified height; content may clip
|
|
721
|
+
/// HeightRuleValues.AtLeast — row is at least the specified height; expands for content
|
|
722
|
+
/// HeightRuleValues.Auto — row height determined by content (default)
|
|
723
|
+
///
|
|
724
|
+
/// Height value is in DXA (twentieths of a point). 1440 DXA = 1 inch.
|
|
725
|
+
/// </summary>
|
|
726
|
+
public static void SetRowHeight(TableRow row)
|
|
727
|
+
{
|
|
728
|
+
var trPr = row.GetFirstChild<TableRowProperties>()
|
|
729
|
+
?? row.PrependChild(new TableRowProperties());
|
|
730
|
+
|
|
731
|
+
// Option A: Exact height of 0.5 inch (720 DXA)
|
|
732
|
+
trPr.Append(new TableRowHeight
|
|
733
|
+
{
|
|
734
|
+
Val = 720, // 0.5 inch in DXA
|
|
735
|
+
HeightType = HeightRuleValues.Exact
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
// Option B: Minimum height (grows if content needs more)
|
|
739
|
+
// trPr.Append(new TableRowHeight
|
|
740
|
+
// {
|
|
741
|
+
// Val = 360, // 0.25 inch minimum
|
|
742
|
+
// HeightType = HeightRuleValues.AtLeast
|
|
743
|
+
// });
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// ──────────────────────────────────────────────────────────────
|
|
747
|
+
// 13. SetHeaderRowRepeat — repeat on each page
|
|
748
|
+
// ──────────────────────────────────────────────────────────────
|
|
749
|
+
/// <summary>
|
|
750
|
+
/// Marks a row as a header row that repeats at the top of each page
|
|
751
|
+
/// when the table spans multiple pages.
|
|
752
|
+
///
|
|
753
|
+
/// XML:
|
|
754
|
+
/// <w:trPr>
|
|
755
|
+
/// <w:tblHeader/>
|
|
756
|
+
/// </w:trPr>
|
|
757
|
+
///
|
|
758
|
+
/// GOTCHA: Only works on contiguous rows starting from the FIRST row of the table.
|
|
759
|
+
/// If row 1 and row 2 are both headers, both must have TableHeader set.
|
|
760
|
+
/// You cannot make row 3 a repeating header if row 2 is not.
|
|
761
|
+
/// </summary>
|
|
762
|
+
public static void SetHeaderRowRepeat(TableRow row)
|
|
763
|
+
{
|
|
764
|
+
var trPr = row.GetFirstChild<TableRowProperties>()
|
|
765
|
+
?? row.PrependChild(new TableRowProperties());
|
|
766
|
+
|
|
767
|
+
trPr.Append(new TableHeader());
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// ──────────────────────────────────────────────────────────────
|
|
771
|
+
// 14. SetPerCellBorders — override table borders on specific cells
|
|
772
|
+
// ──────────────────────────────────────────────────────────────
|
|
773
|
+
/// <summary>
|
|
774
|
+
/// Overrides the table-level borders for a specific cell.
|
|
775
|
+
/// Per-cell borders take precedence over table-level borders.
|
|
776
|
+
///
|
|
777
|
+
/// XML:
|
|
778
|
+
/// <w:tcPr>
|
|
779
|
+
/// <w:tcBorders>
|
|
780
|
+
/// <w:top w:val="double" w:sz="4" w:space="0" w:color="FF0000"/>
|
|
781
|
+
/// <w:bottom w:val="single" w:sz="12" w:space="0" w:color="0000FF"/>
|
|
782
|
+
/// <w:start w:val="none" w:sz="0" w:space="0" w:color="auto"/>
|
|
783
|
+
/// <w:end w:val="none" w:sz="0" w:space="0" w:color="auto"/>
|
|
784
|
+
/// </w:tcBorders>
|
|
785
|
+
/// </w:tcPr>
|
|
786
|
+
///
|
|
787
|
+
/// GOTCHA: When two adjacent cells define conflicting borders, the conflict
|
|
788
|
+
/// resolution follows the ECMA-376 spec: wider borders win; if same width,
|
|
789
|
+
/// the cell on the "end" side wins.
|
|
790
|
+
/// </summary>
|
|
791
|
+
public static void SetPerCellBorders(TableCell cell)
|
|
792
|
+
{
|
|
793
|
+
var tcPr = cell.GetFirstChild<TableCellProperties>()
|
|
794
|
+
?? cell.PrependChild(new TableCellProperties());
|
|
795
|
+
|
|
796
|
+
tcPr.TableCellBorders = new TableCellBorders(
|
|
797
|
+
new TopBorder { Val = BorderValues.Double, Size = 4, Space = 0, Color = "FF0000" },
|
|
798
|
+
new BottomBorder { Val = BorderValues.Single, Size = 12, Space = 0, Color = "0000FF" },
|
|
799
|
+
new LeftBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" },
|
|
800
|
+
new RightBorder { Val = BorderValues.None, Size = 0, Space = 0, Color = "auto" }
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// ──────────────────────────────────────────────────────────────
|
|
805
|
+
// 15. CreateHorizontalMerge — GridSpan (column span)
|
|
806
|
+
// ──────────────────────────────────────────────────────────────
|
|
807
|
+
/// <summary>
|
|
808
|
+
/// Creates a row with horizontal cell merging using GridSpan.
|
|
809
|
+
///
|
|
810
|
+
/// To merge 3 columns into one cell, set GridSpan.Val = 3 on that cell.
|
|
811
|
+
/// The row still references the same grid columns, but one cell spans multiple.
|
|
812
|
+
///
|
|
813
|
+
/// XML for a row in a 4-column table where first cell spans columns 1-3:
|
|
814
|
+
/// <w:tr>
|
|
815
|
+
/// <w:tc>
|
|
816
|
+
/// <w:tcPr>
|
|
817
|
+
/// <w:gridSpan w:val="3"/> <!-- this cell spans 3 grid columns -->
|
|
818
|
+
/// </w:tcPr>
|
|
819
|
+
/// <w:p><w:r><w:t>Merged across 3 columns</w:t></w:r></w:p>
|
|
820
|
+
/// </w:tc>
|
|
821
|
+
/// <w:tc>
|
|
822
|
+
/// <w:p><w:r><w:t>Normal cell</w:t></w:r></w:p>
|
|
823
|
+
/// </w:tc>
|
|
824
|
+
/// </w:tr>
|
|
825
|
+
///
|
|
826
|
+
/// GOTCHA: The total GridSpan values across all cells in a row must equal
|
|
827
|
+
/// the number of GridColumn elements in TblGrid.
|
|
828
|
+
/// </summary>
|
|
829
|
+
public static TableRow CreateHorizontalMerge(TableRow row)
|
|
830
|
+
{
|
|
831
|
+
// Assume a 4-column grid: first cell spans 3 columns, second cell is normal
|
|
832
|
+
|
|
833
|
+
// Cell spanning 3 columns
|
|
834
|
+
var mergedCell = new TableCell(
|
|
835
|
+
new TableCellProperties(
|
|
836
|
+
new GridSpan { Val = 3 }),
|
|
837
|
+
new Paragraph(
|
|
838
|
+
new Run(new Text("This cell spans 3 columns"))));
|
|
839
|
+
row.Append(mergedCell);
|
|
840
|
+
|
|
841
|
+
// Normal cell (1 column, GridSpan defaults to 1 when omitted)
|
|
842
|
+
var normalCell = new TableCell(
|
|
843
|
+
new Paragraph(
|
|
844
|
+
new Run(new Text("Normal cell"))));
|
|
845
|
+
row.Append(normalCell);
|
|
846
|
+
|
|
847
|
+
return row;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// ──────────────────────────────────────────────────────────────
|
|
851
|
+
// 16. CreateVerticalMerge — VerticalMerge Restart + Continue
|
|
852
|
+
// ──────────────────────────────────────────────────────────────
|
|
853
|
+
/// <summary>
|
|
854
|
+
/// Creates vertical cell merging using VerticalMerge with Restart/Continue pattern.
|
|
855
|
+
///
|
|
856
|
+
/// Vertical merge pattern:
|
|
857
|
+
/// - First row: VerticalMerge.Val = MergedCellValues.Restart (starts the merge)
|
|
858
|
+
/// - Subsequent rows: VerticalMerge.Val = MergedCellValues.Continue (continues)
|
|
859
|
+
/// - Last continuation can also use VerticalMerge with no Val attribute
|
|
860
|
+
///
|
|
861
|
+
/// XML:
|
|
862
|
+
/// Row 1: <w:tcPr><w:vMerge w:val="restart"/></w:tcPr>
|
|
863
|
+
/// <w:p><w:r><w:t>Visible content</w:t></w:r></w:p>
|
|
864
|
+
/// Row 2: <w:tcPr><w:vMerge/></w:tcPr>
|
|
865
|
+
/// <w:p/> <!-- MUST still have a paragraph, even though cell is merged -->
|
|
866
|
+
/// Row 3: <w:tcPr><w:vMerge/></w:tcPr>
|
|
867
|
+
/// <w:p/> <!-- MUST still have a paragraph -->
|
|
868
|
+
///
|
|
869
|
+
/// GOTCHA: The "continue" cells MUST still contain at least one empty Paragraph.
|
|
870
|
+
/// They also MUST have the same column position in the grid as the "restart" cell.
|
|
871
|
+
/// </summary>
|
|
872
|
+
public static Table CreateVerticalMerge(Table table)
|
|
873
|
+
{
|
|
874
|
+
var grid = new TableGrid(
|
|
875
|
+
new GridColumn { Width = "3120" },
|
|
876
|
+
new GridColumn { Width = "3120" },
|
|
877
|
+
new GridColumn { Width = "3120" });
|
|
878
|
+
// Only add grid if not already present
|
|
879
|
+
if (table.GetFirstChild<TableGrid>() == null)
|
|
880
|
+
{
|
|
881
|
+
var tblPr = table.GetFirstChild<TableProperties>();
|
|
882
|
+
if (tblPr != null)
|
|
883
|
+
tblPr.InsertAfterSelf(grid);
|
|
884
|
+
else
|
|
885
|
+
table.PrependChild(grid);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// Row 1: first cell starts vertical merge
|
|
889
|
+
var row1 = new TableRow(
|
|
890
|
+
new TableCell(
|
|
891
|
+
new TableCellProperties(
|
|
892
|
+
new VerticalMerge { Val = MergedCellValues.Restart }), // Start merge
|
|
893
|
+
new Paragraph(new Run(new Text("Spans 3 rows")))),
|
|
894
|
+
new TableCell(
|
|
895
|
+
new Paragraph(new Run(new Text("Row 1, Col 2")))),
|
|
896
|
+
new TableCell(
|
|
897
|
+
new Paragraph(new Run(new Text("Row 1, Col 3")))));
|
|
898
|
+
table.Append(row1);
|
|
899
|
+
|
|
900
|
+
// Row 2: first cell continues vertical merge
|
|
901
|
+
var row2 = new TableRow(
|
|
902
|
+
new TableCell(
|
|
903
|
+
new TableCellProperties(
|
|
904
|
+
new VerticalMerge()), // Continue (no Val)
|
|
905
|
+
new Paragraph()), // Empty paragraph required!
|
|
906
|
+
new TableCell(
|
|
907
|
+
new Paragraph(new Run(new Text("Row 2, Col 2")))),
|
|
908
|
+
new TableCell(
|
|
909
|
+
new Paragraph(new Run(new Text("Row 2, Col 3")))));
|
|
910
|
+
table.Append(row2);
|
|
911
|
+
|
|
912
|
+
// Row 3: first cell continues vertical merge
|
|
913
|
+
var row3 = new TableRow(
|
|
914
|
+
new TableCell(
|
|
915
|
+
new TableCellProperties(
|
|
916
|
+
new VerticalMerge()), // Continue
|
|
917
|
+
new Paragraph()), // Empty paragraph required!
|
|
918
|
+
new TableCell(
|
|
919
|
+
new Paragraph(new Run(new Text("Row 3, Col 2")))),
|
|
920
|
+
new TableCell(
|
|
921
|
+
new Paragraph(new Run(new Text("Row 3, Col 3")))));
|
|
922
|
+
table.Append(row3);
|
|
923
|
+
|
|
924
|
+
return table;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// ──────────────────────────────────────────────────────────────
|
|
928
|
+
// 17. CreateNestedTable — table inside a table cell
|
|
929
|
+
// ──────────────────────────────────────────────────────────────
|
|
930
|
+
/// <summary>
|
|
931
|
+
/// Inserts a table inside a table cell.
|
|
932
|
+
///
|
|
933
|
+
/// GOTCHA: The nested table is a direct child of the TableCell, placed BEFORE
|
|
934
|
+
/// the required trailing Paragraph. The cell structure is:
|
|
935
|
+
///
|
|
936
|
+
/// <w:tc>
|
|
937
|
+
/// <w:tcPr>...</w:tcPr>
|
|
938
|
+
/// <w:tbl> <!-- nested table -->
|
|
939
|
+
/// <w:tblPr>...</w:tblPr>
|
|
940
|
+
/// <w:tblGrid>...</w:tblGrid>
|
|
941
|
+
/// <w:tr>...</w:tr>
|
|
942
|
+
/// </w:tbl>
|
|
943
|
+
/// <w:p/> <!-- REQUIRED trailing paragraph -->
|
|
944
|
+
/// </w:tc>
|
|
945
|
+
///
|
|
946
|
+
/// GOTCHA: The parent cell still MUST end with a Paragraph after the nested table.
|
|
947
|
+
/// </summary>
|
|
948
|
+
public static Table CreateNestedTable(TableCell parentCell)
|
|
949
|
+
{
|
|
950
|
+
var nestedTable = new Table();
|
|
951
|
+
|
|
952
|
+
var tblPr = new TableProperties(
|
|
953
|
+
new TableWidth { Width = "5000", Type = TableWidthUnitValues.Pct },
|
|
954
|
+
new TableBorders(
|
|
955
|
+
new TopBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "999999" },
|
|
956
|
+
new LeftBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "999999" },
|
|
957
|
+
new BottomBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "999999" },
|
|
958
|
+
new RightBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "999999" },
|
|
959
|
+
new InsideHorizontalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "999999" },
|
|
960
|
+
new InsideVerticalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "999999" }
|
|
961
|
+
));
|
|
962
|
+
nestedTable.Append(tblPr);
|
|
963
|
+
|
|
964
|
+
var grid = new TableGrid(
|
|
965
|
+
new GridColumn { Width = "2000" },
|
|
966
|
+
new GridColumn { Width = "2000" });
|
|
967
|
+
nestedTable.Append(grid);
|
|
968
|
+
|
|
969
|
+
// 2x2 nested table
|
|
970
|
+
for (int r = 0; r < 2; r++)
|
|
971
|
+
{
|
|
972
|
+
var row = new TableRow();
|
|
973
|
+
for (int c = 0; c < 2; c++)
|
|
974
|
+
{
|
|
975
|
+
var cell = new TableCell(
|
|
976
|
+
new Paragraph(
|
|
977
|
+
new Run(new Text($"Nested R{r + 1}C{c + 1}"))));
|
|
978
|
+
row.Append(cell);
|
|
979
|
+
}
|
|
980
|
+
nestedTable.Append(row);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// Insert the nested table in the parent cell.
|
|
984
|
+
// The parent cell must still end with a paragraph.
|
|
985
|
+
parentCell.Append(nestedTable);
|
|
986
|
+
parentCell.Append(new Paragraph()); // REQUIRED trailing paragraph
|
|
987
|
+
|
|
988
|
+
return nestedTable;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
// ──────────────────────────────────────────────────────────────
|
|
992
|
+
// 18. CreateFloatingTable — absolute positioning
|
|
993
|
+
// ──────────────────────────────────────────────────────────────
|
|
994
|
+
/// <summary>
|
|
995
|
+
/// Creates a floating (absolutely positioned) table using TablePositionProperties.
|
|
996
|
+
///
|
|
997
|
+
/// XML:
|
|
998
|
+
/// <w:tblPr>
|
|
999
|
+
/// <w:tblpPr
|
|
1000
|
+
/// w:leftFromText="180"
|
|
1001
|
+
/// w:rightFromText="180"
|
|
1002
|
+
/// w:topFromText="180"
|
|
1003
|
+
/// w:bottomFromText="180"
|
|
1004
|
+
/// w:vertAnchor="page"
|
|
1005
|
+
/// w:horzAnchor="page"
|
|
1006
|
+
/// w:tblpX="2880"
|
|
1007
|
+
/// w:tblpY="4320"/>
|
|
1008
|
+
/// </w:tblPr>
|
|
1009
|
+
///
|
|
1010
|
+
/// Anchor values:
|
|
1011
|
+
/// VerticalAnchorValues.Page / Margin / Text
|
|
1012
|
+
/// HorizontalAnchorValues.Page / Margin / Text
|
|
1013
|
+
///
|
|
1014
|
+
/// Position values (tblpX, tblpY) are in DXA from the anchor.
|
|
1015
|
+
/// FromText values are spacing between table and surrounding text, in DXA.
|
|
1016
|
+
///
|
|
1017
|
+
/// GOTCHA: Floating tables allow text to wrap around them, similar to
|
|
1018
|
+
/// text-wrapped images. This can produce unexpected layouts.
|
|
1019
|
+
/// </summary>
|
|
1020
|
+
public static Table CreateFloatingTable(Body body)
|
|
1021
|
+
{
|
|
1022
|
+
var table = new Table();
|
|
1023
|
+
|
|
1024
|
+
var tblPr = new TableProperties();
|
|
1025
|
+
|
|
1026
|
+
// Floating position: 2 inches from left of page, 3 inches from top of page
|
|
1027
|
+
tblPr.TablePositionProperties = new TablePositionProperties
|
|
1028
|
+
{
|
|
1029
|
+
LeftFromText = 180, // 0.125" spacing from text
|
|
1030
|
+
RightFromText = 180,
|
|
1031
|
+
TopFromText = 180,
|
|
1032
|
+
BottomFromText = 180,
|
|
1033
|
+
VerticalAnchor = VerticalAnchorValues.Page,
|
|
1034
|
+
HorizontalAnchor = HorizontalAnchorValues.Page,
|
|
1035
|
+
TablePositionX = 2880, // 2 inches from left edge of page
|
|
1036
|
+
TablePositionY = 4320 // 3 inches from top of page
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
tblPr.Append(new TableWidth { Width = "3600", Type = TableWidthUnitValues.Dxa });
|
|
1040
|
+
tblPr.Append(new TableBorders(
|
|
1041
|
+
new TopBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
1042
|
+
new LeftBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
1043
|
+
new BottomBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
1044
|
+
new RightBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
1045
|
+
new InsideHorizontalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" },
|
|
1046
|
+
new InsideVerticalBorder { Val = BorderValues.Single, Size = 4, Space = 0, Color = "000000" }
|
|
1047
|
+
));
|
|
1048
|
+
table.Append(tblPr);
|
|
1049
|
+
|
|
1050
|
+
var grid = new TableGrid(
|
|
1051
|
+
new GridColumn { Width = "1800" },
|
|
1052
|
+
new GridColumn { Width = "1800" });
|
|
1053
|
+
table.Append(grid);
|
|
1054
|
+
|
|
1055
|
+
// Simple 2x2 floating table
|
|
1056
|
+
for (int r = 0; r < 2; r++)
|
|
1057
|
+
{
|
|
1058
|
+
var row = new TableRow();
|
|
1059
|
+
for (int c = 0; c < 2; c++)
|
|
1060
|
+
{
|
|
1061
|
+
var cell = new TableCell(
|
|
1062
|
+
new Paragraph(
|
|
1063
|
+
new Run(new Text($"Float R{r + 1}C{c + 1}"))));
|
|
1064
|
+
row.Append(cell);
|
|
1065
|
+
}
|
|
1066
|
+
table.Append(row);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
body.Append(table);
|
|
1070
|
+
return table;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
// ──────────────────────────────────────────────────────────────
|
|
1074
|
+
// 19. ApplyTableLook — conditional formatting flags
|
|
1075
|
+
// ──────────────────────────────────────────────────────────────
|
|
1076
|
+
/// <summary>
|
|
1077
|
+
/// Sets the TableLook element which controls which parts of a table style are applied.
|
|
1078
|
+
///
|
|
1079
|
+
/// XML:
|
|
1080
|
+
/// <w:tblPr>
|
|
1081
|
+
/// <w:tblLook w:val="04A0"
|
|
1082
|
+
/// w:firstRow="1"
|
|
1083
|
+
/// w:lastRow="0"
|
|
1084
|
+
/// w:firstColumn="1"
|
|
1085
|
+
/// w:lastColumn="0"
|
|
1086
|
+
/// w:noHBand="0"
|
|
1087
|
+
/// w:noVBand="1"/>
|
|
1088
|
+
/// </w:tblPr>
|
|
1089
|
+
///
|
|
1090
|
+
/// These flags control conditional formatting from the applied table style:
|
|
1091
|
+
/// FirstRow = apply special header row formatting
|
|
1092
|
+
/// LastRow = apply special last row formatting
|
|
1093
|
+
/// FirstColumn = apply special first column formatting
|
|
1094
|
+
/// LastColumn = apply special last column formatting
|
|
1095
|
+
/// NoHorizontalBand = disable banded row shading
|
|
1096
|
+
/// NoVerticalBand = disable banded column shading
|
|
1097
|
+
///
|
|
1098
|
+
/// The Val attribute is a bitmask but the individual boolean attributes are preferred.
|
|
1099
|
+
/// </summary>
|
|
1100
|
+
public static void ApplyTableLook(Table table)
|
|
1101
|
+
{
|
|
1102
|
+
var tblPr = table.GetFirstChild<TableProperties>()
|
|
1103
|
+
?? table.PrependChild(new TableProperties());
|
|
1104
|
+
|
|
1105
|
+
tblPr.TableLook = new TableLook
|
|
1106
|
+
{
|
|
1107
|
+
Val = "04A0",
|
|
1108
|
+
FirstRow = true,
|
|
1109
|
+
LastRow = false,
|
|
1110
|
+
FirstColumn = true,
|
|
1111
|
+
LastColumn = false,
|
|
1112
|
+
NoHorizontalBand = false, // false = DO apply banded row shading
|
|
1113
|
+
NoVerticalBand = true // true = do NOT apply banded column shading
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// ──────────────────────────────────────────────────────────────
|
|
1118
|
+
// 20. ApplyTableStyle — reference a named style
|
|
1119
|
+
// ──────────────────────────────────────────────────────────────
|
|
1120
|
+
/// <summary>
|
|
1121
|
+
/// References a named table style defined in the styles part.
|
|
1122
|
+
///
|
|
1123
|
+
/// XML:
|
|
1124
|
+
/// <w:tblPr>
|
|
1125
|
+
/// <w:tblStyle w:val="TableGrid"/>
|
|
1126
|
+
/// </w:tblPr>
|
|
1127
|
+
///
|
|
1128
|
+
/// Common built-in style IDs:
|
|
1129
|
+
/// "TableGrid" — basic grid with all borders
|
|
1130
|
+
/// "TableNormal" — no borders or shading
|
|
1131
|
+
/// "LightShading" — light shading style
|
|
1132
|
+
/// "MediumShading1" — medium shading
|
|
1133
|
+
/// "GridTable4-Accent1" — colorful banded table (Office 2013+)
|
|
1134
|
+
///
|
|
1135
|
+
/// GOTCHA: The style ID must exist in the StyleDefinitionsPart. If you reference
|
|
1136
|
+
/// a style that doesn't exist, Word will silently ignore it and use defaults.
|
|
1137
|
+
/// Built-in styles are only available if they have been added to the styles part
|
|
1138
|
+
/// (Word adds them lazily on first use).
|
|
1139
|
+
///
|
|
1140
|
+
/// GOTCHA: Combine with TableLook to control which conditional parts of the
|
|
1141
|
+
/// style are applied (header row, banded rows, etc.).
|
|
1142
|
+
/// </summary>
|
|
1143
|
+
public static void ApplyTableStyle(Table table)
|
|
1144
|
+
{
|
|
1145
|
+
var tblPr = table.GetFirstChild<TableProperties>()
|
|
1146
|
+
?? table.PrependChild(new TableProperties());
|
|
1147
|
+
|
|
1148
|
+
// Reference the "TableGrid" built-in style
|
|
1149
|
+
tblPr.TableStyle = new TableStyle { Val = "TableGrid" };
|
|
1150
|
+
|
|
1151
|
+
// Combine with TableLook for conditional formatting
|
|
1152
|
+
tblPr.TableLook = new TableLook
|
|
1153
|
+
{
|
|
1154
|
+
Val = "04A0",
|
|
1155
|
+
FirstRow = true,
|
|
1156
|
+
LastRow = false,
|
|
1157
|
+
FirstColumn = true,
|
|
1158
|
+
LastColumn = false,
|
|
1159
|
+
NoHorizontalBand = false,
|
|
1160
|
+
NoVerticalBand = true
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
}
|