Thanks to visit codestin.com
Credit goes to github.com

Skip to content

EvotecIT/PSWriteOffice

Repository files navigation

PSWriteOffice

PowerShell-first document automation for Word, Excel, PowerPoint, PDF, RTF, Markdown, CSV, Reader, and Visio, built on top of OfficeIMO.*.

📦 PowerShell Gallery

PowerShell Gallery Version PowerShell Gallery Preview PowerShell Gallery Downloads PowerShell Gallery Platforms

🛠️ Project

Test PowerShell Test .NET Libraries License

Why PSWriteOffice ✨

PSWriteOffice is the PowerShell layer for OfficeIMO.*.

  • OfficeIMO owns the document engine and low-level file-format behavior.
  • PSWriteOffice owns the PowerShell cmdlets, DSL aliases, packaging, examples, and scripting ergonomics.
  • The goal is simple: make Office document automation feel native in PowerShell without requiring Microsoft Office on the machine.

Start here when you want to create polished documents from PowerShell: workbooks with tables, charts, links, images, pivots, and navigation; Word reports with sections, headers, footers, tables, charts, and conversions; PowerPoint decks with reusable slides, notes, sections, themes, and transitions; PDFs with composition, extraction, forms, stamps, and metadata; RTF documents and bridges; Markdown and CSV workflows; Visio diagrams; and unified readback for existing files.

Platform Areas 🧭

Area Status What it covers now
Word Mature Document creation, readers, bookmarks, content controls, fields, HTML conversion, Markdown conversion
Excel Advanced Sheets, tables, named ranges, formulas, validation, charts, pivots, comments, TOC/navigation, explicit range readers, chart formatting, smarter links, URL images, summary-sheet linking
PowerPoint Experimental but useful Slides, titles, text boxes, bullets, notes, layouts, placeholders, sections, text replacement, slide import, slide copy, transitions, sizing
PDF Advanced New PDFs, text, headings, images, tables, panels, bookmarks, metadata, attachments, stamps, watermarks, forms, merge/split/copy/move pages, HTML conversion, text/image/attachment extraction, compliance inspection
RTF Solid Create/read/update .rtf, replace text, append paragraphs, edit document properties, convert RTF to Word/HTML/PDF, convert Word/HTML to RTF, and read semantic chunks through Reader
Markdown Solid Read Markdown, inspect full object trees/headings/front matter/tables, build Markdown with a DSL, render HTML, convert HTML
CSV Solid Read CSV, emit CSV, object-focused data workflows
Reader New Unified chunk/document/table/visual/asset/ingest readback over Word, Excel, PowerPoint, Markdown, PDF, RTF, HTML, CSV, JSON, XML, YAML, ZIP, EPUB, Visio, and text-like files through OfficeIMO.Reader
Visio New DSL diagram creation, built-in and package-backed stencils, create/load/save .vsdx, inspect diagrams, generate galleries, export stencil preview galleries, and export SVG/PNG through OfficeIMO.Visio

Quick Start 🚀

Word

New-OfficeWord -Path .\Report.docx {
    WordSection {
        WordHeader { WordParagraph -Text 'Quarterly Report' -Style Heading2 }
        WordFooter { WordPageNumber }
        WordParagraph -Text 'Hello from PSWriteOffice.'
        WordList -Style Bulleted {
            WordListItem -Text 'Alpha'
            WordListItem -Text 'Beta'
        }
    }
}
$chartData = @(
    [PSCustomObject]@{ Region = 'NA'; Revenue = 100 }
    [PSCustomObject]@{ Region = 'EMEA'; Revenue = 200 }
)

New-OfficeWord -Path .\Charts.docx {
    Add-OfficeWordChart -Type Pie -Data $chartData -CategoryProperty Region -SeriesProperty Revenue -Title 'Revenue Mix'
}

Excel

$data = @(
    [PSCustomObject]@{ Region = 'NA'; Revenue = 100 }
    [PSCustomObject]@{ Region = 'EMEA'; Revenue = 200 }
)

New-OfficeExcel -Path .\Report.xlsx {
    ExcelSheet 'Data' {
        ExcelTable -Data $data -TableName 'Sales' -AutoFit
        ExcelNamedRange -Name 'SalesData' -Range 'A1:B3'
    }
    ExcelSheet 'Notes' {
        ExcelRow -Row 1 -Values 'Label', 'Value'
        ExcelRow -Row 2 -Values 'Generated', (Get-Date -Format 'yyyy-MM-dd')
    }
    ExcelTableOfContents -IncludeNamedRanges
}

PowerPoint

New-OfficePowerPoint -Path .\Deck.pptx {
    PptSlide {
        PptTitle -Title 'Status Update'
        PptTextBox -Text 'Generated with PSWriteOffice' -X 80 -Y 150 -Width 360 -Height 60
        PptBullets -Bullets 'Wins','Risks','Next Steps' -X 430 -Y 150 -Width 260 -Height 200
        PptNotes -Text 'Keep this under five minutes.'
    }
}
$ppt = Get-OfficePowerPoint -FilePath .\Deck.pptx
Add-OfficePowerPointSection -Presentation $ppt -Name 'Intro' -StartSlideIndex 0
Rename-OfficePowerPointSection -Presentation $ppt -Name 'Intro' -NewName 'Opening'
Update-OfficePowerPointText -Presentation $ppt -OldValue 'FY24' -NewValue 'FY25' -IncludeNotes
Copy-OfficePowerPointSlide -Presentation $ppt -Index 0
Get-OfficePowerPointSlide -Presentation $ppt -Index 0 | Set-OfficePowerPointSlideTransition -Transition Fade
Set-OfficePowerPointSlideSize -Presentation $ppt -Preset Screen16x9
Import-OfficePowerPointSlide -Presentation $ppt -SourcePath .\SourceDeck.pptx -SourceIndex 0

PowerPoint theme and layout helpers

$ppt = Get-OfficePowerPoint -FilePath .\Deck.pptx
Set-OfficePowerPointThemeColor -Presentation $ppt -Colors @{ Accent1 = '#C00000'; Accent2 = '#00B0F0' } -AllMasters
Set-OfficePowerPointThemeFonts -Presentation $ppt -MajorLatin 'Aptos' -MinorLatin 'Calibri' -AllMasters
Set-OfficePowerPointThemeName -Presentation $ppt -Name 'Contoso Theme' -AllMasters
Get-OfficePowerPointSlide -Presentation $ppt -Index 0 | Set-OfficePowerPointSlideLayout -LayoutName 'Title and Content'
Get-OfficePowerPointTheme -Presentation $ppt

PDF

$rows = @(
    [PSCustomObject]@{ Area = 'Word'; Status = 'Ready'; Owner = 'Docs' }
    [PSCustomObject]@{ Area = 'PDF'; Status = 'Review'; Owner = 'Adapters' }
)

New-OfficePdf -Path .\Status.pdf {
    Add-OfficePdfHeading -Text 'Documentation Status' -Level 1
    Add-OfficePdfParagraph -Text 'Generated with PSWriteOffice through OfficeIMO.Pdf.'
    Add-OfficePdfTable -InputObject $rows -Property Area,Status,Owner -Header 'Area','Status','Owner' -Align Center
    Add-OfficePdfBookmark -Name 'Status table'
    Set-OfficePdfMetadata -Title 'Documentation Status' -Author 'PSWriteOffice'
}
Join-OfficePdf -Path .\Cover.pdf, .\Status.pdf -OutputPath .\Report.pdf
Split-OfficePdf -Path .\Report.pdf -OutputDirectory .\Pages
Get-OfficePdfText -Path .\Report.pdf

Excel chart finishing

$chart = Add-OfficeExcelChart -TableName 'Sales' -Row 6 -Column 1 -Type Pie -Title 'Revenue Mix' -PassThru
$chart |
    Set-OfficeExcelChartLegend -Position Right |
    Set-OfficeExcelChartDataLabels -ShowValue $true -ShowPercent $true -Position OutsideEnd -NumberFormat '0.0%' -SourceLinked:$false |
    Set-OfficeExcelChartStyle -StyleId 251 -ColorStyleId 10

Excel links and media

ExcelSheet 'Data' {
    Set-OfficeExcelSmartHyperlink -Address 'A2' -Url 'https://datatracker.ietf.org/doc/html/rfc7208'
    Set-OfficeExcelHostHyperlink -Address 'B2' -Url 'https://learn.microsoft.com/office/open-xml/'
    Add-OfficeExcelImageFromUrl -Address 'D2' -Url 'https://example.org/logo.png' -WidthPixels 48 -HeightPixels 48
}

Excel internal navigation

ExcelSheet 'Summary' {
    Set-OfficeExcelInternalLinks -Range 'D2:D10'
    Set-OfficeExcelInternalLinksByHeader -Header 'Sheet' -TableName 'SummaryTable' -DisplayScript { param($text) "Open $text" }
}

Excel external link automation

ExcelSheet 'Summary' {
    Set-OfficeExcelUrlLinksByHeader -Header 'RFC' -TableName 'LinksTable' -UrlScript { param($text) "https://datatracker.ietf.org/doc/html/$text" } -TitleScript { param($text) "Open $text" }
    Set-OfficeExcelUrlLinks -Range 'D2:D10' -UrlScript { param($text) "https://datatracker.ietf.org/doc/html/$text" }
}

RTF

New-OfficeRtf -OutputPath .\Report.rtf -Text 'Summary', 'Ready for review'
Get-OfficeRtf -Path .\Report.rtf
Update-OfficeRtfText -Path .\Report.rtf -OutputPath .\Report-Updated.rtf -OldText 'review' -NewText 'release'
ConvertFrom-OfficeRtf -Path .\Report-Updated.rtf -As Pdf -OutputPath .\Report.pdf
Get-OfficeDocumentChunk -Path .\Report-Updated.rtf

Markdown and CSV

New-OfficeMarkdown -Path .\README.md {
    MarkdownHeading -Level 1 -Text 'Report'
    MarkdownParagraph -Text 'Generated by PSWriteOffice.'
}

$data | ConvertTo-OfficeCsv -OutputPath .\export.csv

Reader and Visio

Get-OfficeDocumentCapability
Get-OfficeDocumentChunk -Path .\Report.docx
Get-OfficeDocumentChunk -Path .\Report.rtf
Get-OfficeDocument -Path .\Report.pdf -AsJson -Indented
Get-OfficeDocumentAsset -Path .\Deck.pptx -Kind image -OutputDirectory .\reader-assets
New-OfficeVisio -Path .\Diagram.vsdx -Title 'Service map' -RequestRecalcOnOpen {
    VisioRectangle -Key web -Text 'Web' -X 1.5 -Y 4 -Width 1.5 -Height 0.8 -FillColor LightBlue -LineColor SteelBlue
    VisioDiamond -Key decision -Text 'Ready?' -X 4 -Y 4 -Width 1.2 -Height 1 -FillColor '#FFF2CC' -LineColor '#B45309'
    VisioRectangle -Key api -Text 'API' -X 6.2 -Y 4 -Width 1.5 -Height 0.8 -FillColor LightGreen -LineColor SeaGreen
    VisioConnector -From web -To decision -Kind RightAngle -EndArrow Triangle -Label 'check'
    VisioConnector -From decision -To api -Kind RightAngle -EndArrow Triangle -Label 'ship'
}

Get-OfficeVisioInfo -Path .\Diagram.vsdx -AsText
ConvertTo-OfficeVisioSvg -Path .\Diagram.vsdx -OutputPath .\Diagram.svg
ConvertTo-OfficeVisioPng -Path .\Diagram.vsdx -OutputPath .\Diagram.png
$flow = Get-OfficeVisioStencilCatalog -BuiltIn Flowchart
Find-OfficeVisioStencil -Catalog $flow -Query process -First 5

New-OfficeVisio -Path .\Flow.vsdx -Title 'Stencil flow' -UseMastersByDefault -RequestRecalcOnOpen {
    Import-OfficeVisioStencil -BuiltIn Flowchart -Name Flow -Default
    VisioStencil -Catalog Flow -Stencil process -Key intake -Text 'Intake' -X 1.5 -Y 4 -FillColor '#E0F2FE' -LineColor '#0369A1'
    VisioStencil -Catalog Flow -Stencil decision -Key review -Text 'Review?' -X 4 -Y 4 -FillColor '#FEF3C7' -LineColor '#B45309'
    VisioStencil -Catalog Flow -Stencil data -Key archive -Text 'Archive' -X 6.5 -Y 4 -FillColor '#DCFCE7' -LineColor '#15803D'
    VisioConnector -From intake -To review -Kind RightAngle -EndArrow Triangle -Label 'submit'
    VisioConnector -From review -To archive -Kind RightAngle -EndArrow Triangle -Label 'store'
}
$catalog = Get-OfficeVisioStencilCatalog -Path .\MyShapes.vssx -CatalogName 'Custom Shapes' -IncludeUnsupportedMasters
Find-OfficeVisioStencil -Catalog $catalog -Query server -First 10

New-OfficeVisio -Path .\CustomStencil.vsdx -UseMastersByDefault {
    Import-OfficeVisioStencil -Catalog $catalog -Name Custom -Default
    VisioStencil -Stencil server -Key server -Text 'Server' -X 2 -Y 4
    VisioStencil -Stencil database -Key database -Text 'Database' -X 5 -Y 4
    VisioConnector -From server -To database -Kind RightAngle -EndArrow Triangle
}

More visual Visio examples live in Examples\Visio. Run .\Examples\Visio\Build-VisioShowcase.ps1 to generate editable .vsdx files plus SVG/PNG previews for stencil flowcharts, architecture maps, network topology, and package-backed stencil loading.

New-OfficeVisioGallery -OutputDirectory .\VisioGallery |
    Select-Object Name, FilePath, IsClean

Export-OfficeVisioStencilPreviewGallery -Path .\MyShapes.vssx -OutputDirectory .\StencilGallery -Title 'Custom stencil previews'

Read, Inspect, and Convert 🔍

PSWriteOffice is not only about writing files. The module now has stronger read-back and bridge workflows too.

Excel import/export fast path

$data | Export-OfficeExcel -Path .\Report.xlsx -WorksheetName 'Data' -TableName 'Data' -AutoFit -FreezeTopRow
Import-OfficeExcel -Path .\Report.xlsx -WorksheetName 'Data'

Excel benchmark snapshot

The benchmark harness in Benchmarks\Compare-ExcelPerformance.ps1 compares Export-OfficeExcel / Import-OfficeExcel with ImportExcel and ExcelFast on repeatable local workloads. The table below is a local snapshot, not a universal performance promise: hardware, PowerShell version, data shape, formatting, and workbook features all matter.

Run context: PowerShell 7.5.5, AMD Ryzen 9 9950X3D2 16-Core Processor (16 cores / 32 logical processors), 64 GB RAM, Standard suite, median of three runs, measured on 2026-06-22.

Scenario Rows Winner PSWriteOffice 1.0.3 / OfficeIMO.Excel 0.6.47 ImportExcel 7.8.10 ExcelFast 0.0.1-alpha16 Relative time (winner = 1x)
Export objects default 1k PSWriteOffice 16 ms 183 ms 126 ms PSWriteOffice 1x; ImportExcel 11.44x; ExcelFast 7.88x
Export objects default 10k PSWriteOffice 84 ms 1,287 ms 153 ms PSWriteOffice 1x; ImportExcel 15.32x; ExcelFast 1.82x
Export objects default 25k PSWriteOffice 199 ms 3,827 ms 233 ms PSWriteOffice 1x; ImportExcel 19.23x; ExcelFast 1.17x
Export wide objects default 1k PSWriteOffice 26 ms 166 ms 127 ms PSWriteOffice 1x; ImportExcel 6.38x; ExcelFast 4.88x
Export wide objects default 10k PSWriteOffice 256 ms 1,231 ms 296 ms PSWriteOffice 1x; ImportExcel 4.81x; ExcelFast 1.16x
Export wide objects default 25k PSWriteOffice 679 ms 3,832 ms 1,134 ms PSWriteOffice 1x; ImportExcel 5.64x; ExcelFast 1.67x
Import mixed objects full sheet 1k PSWriteOffice 9 ms 52 ms 32 ms PSWriteOffice 1x; ImportExcel 5.78x; ExcelFast 3.56x
Import mixed objects full sheet 10k PSWriteOffice 98 ms 383 ms 311 ms PSWriteOffice 1x; ImportExcel 3.91x; ExcelFast 3.17x
Import mixed objects full sheet 25k PSWriteOffice 333 ms 3,083 ms 881 ms PSWriteOffice 1x; ImportExcel 9.26x; ExcelFast 2.65x
Report workbook with table, chart, pivot, formatting 1k PSWriteOffice 98 ms 214 ms n/a PSWriteOffice 1x; ImportExcel 2.18x; ExcelFast n/a
Report workbook with table, chart, pivot, formatting 10k PSWriteOffice 1,134 ms 1,560 ms n/a PSWriteOffice 1x; ImportExcel 1.38x; ExcelFast n/a
Report workbook with table, chart, pivot, formatting 25k PSWriteOffice 3,677 ms 3,929 ms n/a PSWriteOffice 1x; ImportExcel 1.07x; ExcelFast n/a
Export regional workbook, one table per sheet 1k PSWriteOffice 105 ms 248 ms n/a PSWriteOffice 1x; ImportExcel 2.36x; ExcelFast n/a
Export regional workbook, one table per sheet 10k PSWriteOffice 735 ms 1,509 ms n/a PSWriteOffice 1x; ImportExcel 2.05x; ExcelFast n/a
Export regional workbook, one table per sheet 25k PSWriteOffice 2,003 ms 3,611 ms n/a PSWriteOffice 1x; ImportExcel 1.8x; ExcelFast n/a
Export title, offset header, frozen top row 1k ImportExcel 251 ms 222 ms n/a PSWriteOffice 1.13x; ImportExcel 1x; ExcelFast n/a
Export title, offset header, frozen top row 10k PSWriteOffice 735 ms 1,370 ms n/a PSWriteOffice 1x; ImportExcel 1.86x; ExcelFast n/a
Export title, offset header, frozen top row 25k PSWriteOffice 1,828 ms 3,290 ms n/a PSWriteOffice 1x; ImportExcel 1.8x; ExcelFast n/a
Export data workbook with summary formulas 1k PSWriteOffice 53 ms 192 ms n/a PSWriteOffice 1x; ImportExcel 3.62x; ExcelFast n/a
Export data workbook with summary formulas 10k PSWriteOffice 507 ms 1,449 ms n/a PSWriteOffice 1x; ImportExcel 2.86x; ExcelFast n/a
Export data workbook with summary formulas 25k PSWriteOffice 1,531 ms 3,254 ms n/a PSWriteOffice 1x; ImportExcel 2.13x; ExcelFast n/a

To compare on your machine, run:

pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\Benchmarks\Compare-ExcelPerformance.ps1 -Suite Standard

The benchmark output also records exact module prerelease versions, machine and runtime metadata, per-engine support status, file sizes, and memory deltas in the generated CSV/JSON files. Export scenarios are also opened after generation and checked with Open XML validation when the validator is available. The full scenario list includes append, existing-workbook update, many-sheet, named range, chart-only, pivot-only, and read-focused workloads. See Benchmarks\README.md for the artifact schema and scenario list.

Excel readers

Get-OfficeExcelData -Path .\Report.xlsx -Sheet 'Data'
Get-OfficeExcelRange -Path .\Report.xlsx -Sheet 'Data' -Range 'A1:B10'
Get-OfficeExcelUsedRange -Path .\Report.xlsx -Sheet 'Data' -AsDataTable
Get-OfficeExcelNamedRange -Path .\Report.xlsx
Get-OfficeExcelPivotTable -Path .\Report.xlsx

Word bridges

$markdown = ConvertTo-OfficeWordMarkdown -Path .\Report.docx
ConvertFrom-OfficeWordMarkdown -Markdown $markdown -OutputPath .\Report-Roundtrip.docx
$doc = Get-OfficeWord -Path .\Report.docx
Update-OfficeWordText -Document $doc -OldValue 'FY24' -NewValue 'FY25'
Close-OfficeWord -Document $doc -Save

RTF bridges

ConvertTo-OfficeRtf -WordPath .\Report.docx -OutputPath .\Report.rtf
ConvertTo-OfficeRtf -HtmlPath .\Report.html -OutputPath .\Report-from-html.rtf
ConvertFrom-OfficeRtf -Path .\Report.rtf -As Word -OutputPath .\Report-from-rtf.docx
ConvertFrom-OfficeRtf -Path .\Report.rtf -As Html -OutputPath .\Report.html -IncludeDefaultCss

Word charts with the current API

$doc = New-OfficeWord -Path .\Report.docx
$chart = $doc.AddChart('Revenue Mix')
$chart.AddPie('North America', 125000).
    AddPie('EMEA', 98000).
    AddPie('APAC', 143000) | Out-Null
Close-OfficeWord -Document $doc -Save

Word tables with extra columns

$tableData = $data | Select-Object Region, Revenue,
@{ Name = 'RevenueBand'; Expression = { if ($_.Revenue -gt 100000) { 'High' } else { 'Standard' } } }

New-OfficeWord -Path .\Report.docx {
    Add-OfficeWordTable -InputObject $tableData -Style 'GridTable1LightAccent1'
}

PowerPoint inspection

$ppt = Get-OfficePowerPoint -FilePath .\Deck.pptx
Get-OfficePowerPointSlide -Presentation $ppt
Get-OfficePowerPointSlideSummary -Presentation $ppt
Get-OfficePowerPointNotes -Presentation $ppt
Get-OfficePowerPointShape -Presentation $ppt -Index 0

Recent Highlights 🆕

  • Word to Markdown and Markdown to Word are now surfaced directly through OfficeIMO.Word.Markdown.
  • PDF now has first-class creation, composition, merge/split, page movement, metadata, forms, stamping, attachment, extraction, HTML conversion, and compliance inspection cmdlets. Deeper PDF engine features still belong in OfficeIMO.Pdf first.
  • RTF now has create/read/update/replace cmdlets, Word/HTML/PDF bridges, and semantic Reader chunks through the OfficeIMO.Reader.Rtf adapter.
  • OfficeIMO.Reader is surfaced through chunk, document-envelope, table, visual, asset, ingest, JSON, and capability-discovery cmdlets across the currently registered adapters.
  • OfficeIMO.Visio is surfaced through a first diagram DSL plus built-in and external stencil catalogs, create/load/save, deterministic inspection, reference gallery generation, stencil preview gallery export, and SVG/PNG export cmdlets.
  • Excel now has Add-OfficeExcelTableOfContents, Get-OfficeExcelRange, and Get-OfficeExcelUsedRange.
  • PowerPoint now has section cmdlets, deck-wide text replacement, slide import helpers, slide copy, transitions, slide sizing, theme inspection, theme updates, and layout switching.
  • Excel charts can now be finished with Set-OfficeExcelChartLegend, Set-OfficeExcelChartDataLabels, and Set-OfficeExcelChartStyle.
  • Excel now has discoverable URL-image insertion plus smarter external hyperlink helpers.
  • Excel summary sheets can now auto-link ranges and header-based columns to workbook tabs or external URLs.
  • Backlink placement in Excel TOC flows is safer by default, avoiding overwriting active worksheet data.

Documentation 📚

Use the examples in this README for the first pass, then move to the generated command reference when you need exact parameters and pipeline behavior.

The generated command pages are built from XML comments in the cmdlet source. Prefer contextual examples there too: small workflow snippets with real input data, generated artifacts, readback/validation where useful, and no fake PowerShell compatibility aliases.

Build and Test 🧪

dotnet build .\Sources\PSWriteOffice.sln -c Debug
pwsh -NoLogo -NoProfile -File .\PSWriteOffice.Tests.ps1
pwsh -NoLogo -NoProfile -File .\Build\Validate-PackagedArtefact.ps1

Regenerate the module manifest, generated help, packed artifacts, and website API payloads through the build-module lane:

pwsh -NoLogo -NoProfile -File .\Build\Manage-PSWriteOffice.ps1
pwsh -NoLogo -NoProfile -File .\Build\Export-ApiDocsSnapshot.ps1
pwsh -NoLogo -NoProfile -File .\Build\Measure-CmdletXmlExamples.ps1 -RequireExamples

Development loading is handled through PSWriteOffice.psm1, which prefers the local debug build in Sources\PSWriteOffice\bin\Debug\.

License

MIT

About

PowerShell Module to create and edit Microsoft Word, Microsoft Excel, and Microsoft PowerPoint documents without having Microsoft Office installed.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

  •