EvotecIT / PSWriteOffice

Experimental PowerShell Module to create and edit Microsoft Word, Microsoft Excel, and Microsoft PowerPoint documents without having Microsoft Office installed.
110 stars 9 forks source link

Add Line Breaks #5

Open tobi-coder opened 2 years ago

tobi-coder commented 2 years ago

Hi. What is the correct way to add a line break / new line? I didn't find anything in the examples.

PrzemyslawKlys commented 2 years ago

$Document.AddLineBreak() - as far as I remember - I guess someone should help me out with converting this to PowerShell commands ;)

tobi-coder commented 2 years ago

I tried that without success.

$filePath = "$Env:USERPROFILE\Desktop\$([Guid]::NewGuid()).docx"
$document = [OfficeIMO.Word.WordDocument]::Create($filePath)
$document.AddParagraph("Row1")
$document.AddParagraph("Row2")
$Document.AddLineBreak()
$Document.AddLineBreak()
$Document.AddLineBreak()
$document.AddParagraph("Row3")
$document.Save()

It returns:

Row1
Row2
Row3

but it should be

Row1
Row2

Row3
PrzemyslawKlys commented 2 years ago

Sorry.

$Document.AddParagraph()
$Document.AddParagraph()
$Document.AddParagraph()
$Document.AddParagraph()

Will work adding an empty line.

$Document = New-OfficeWord -FilePath $PSScriptRoot\Documents\DocList.docx

New-OfficeWordText -Document $Document -Text 'This is a test, very big test ', 'and this should be bol' -Bold $null, $true -Underline $null, 'Dashed'

$List = New-OfficeWordList -Document $Document {
    New-OfficeWordListItem -Text 'Test1'
    New-OfficeWordListItem -Text 'Test2'
    New-OfficeWordListItem -Text 'Test3' -Level 2
} -Style Heading1ai

$Document.AddParagraph()
$Document.AddParagraph()
$Document.AddParagraph()
$Document.AddParagraph()

$P1 = New-OfficeWordListItem -Text 'Test4' -List $List

New-OfficeWordText -Document $Document -Text "But lists don't really have to be next to each other" -Bold $true -Alignment Center -Color RoseBud

$P2 = New-OfficeWordListItem -Text 'Test5' -List $List

New-OfficeWordText -Document $Document -Text "Here's another way to define list" -Bold $true -Alignment Center -Color RoseBud

$List1 = $Document.AddList([OfficeIMO.Word.WordListStyle]::Headings111)
$Paragraph1 = $List1.AddItem("Test", 2)
$Paragraph1.FontSize = 24
$Paragraph2 = $List1.AddItem("Test1", 1)
$Paragraph2.Strike = $true
$Paragraph3 = $List1.AddItem("Test2", 0)
$Paragraph3 = $Paragraph3.SetColor([SixLabors.ImageSharp.Color]::Red)

$null = $Document.AddPageBreak()

$P3 = New-OfficeWordListItem -Text 'Test6' -List $List
$P3.Bold = $true
$P3.FontSize = 20

# Get all listitems and find the listitem you want to change
$List.ListItems | Format-Table
$List.ListItems[0].Bold = $true

Save-OfficeWord -Document $Document -Show -FilePath $PSScriptRoot\Documents\Doc1Updated.docx

I've confused it with PageBreak.

GhostyIs1337 commented 2 years ago

@PrzemyslawKlys - How about adding line breaks to text inside tables? :)

edit: would probably be wise to add, that I'm actually adding rows and stuff using the .NET lib so I'm adding text like so:

$table.Rows[($y + $x)].Cells[0].Paragraphs[0].Text = "$($integration.Purpose)"

I saw that you added .AddBreak() to Paragraphs in the .DLL over here https://github.com/EvotecIT/OfficeIMO/pull/39 - but I'm not sure if this .DLL just isn't synced yet, or if AddBreak() is missing from Cells.Paragraphs.

PrzemyslawKlys commented 2 years ago

It's a few versions behind, but this could work

$table.Rows[($y + $x)].Cells[0].Paragraphs[0].AddParagraph()
GhostyIs1337 commented 2 years ago
Method invocation failed because [OfficeIMO.Word.WordParagraph] does not contain a method named 'AddParagraph'. 

:)

I've figured it out though, I was adding .AddParagraphAfterSelf() and .AddParagraphBeforeSelf() in reverse.

This works fine now though:

            $table.Rows[($y + $x)].Cells[0].MergeHorizontally(6, 0)
            $table.Rows[($y + $x)].Cells[0].Paragraphs[0].AddParagraphAfterSelf()
            $table.Rows[($y + $x)].Cells[0].Paragraphs[0].Text = "$($integration.Purpose)"
            $table.Rows[($y + $x)].Cells[0].Paragraphs[0].ParagraphAlignment = "Center"
            $table.Rows[($y + $x)].Cells[0].Paragraphs[0].AddParagraphBeforeSelf()

Now just have to figure out how to add it to $OFS :D

GhostyIs1337 commented 2 years ago

@PrzemyslawKlys Hey, do you have some input? I can't seem to figure out how to add line breaks here:

$inboundStringBuilder = [System.Text.StringBuilder]""
$commentStringBuilder = [System.Text.StringBuilder]""

foreach ($jsonBuild in ($integration.Rule | where { $_.Type -eq "Inbound" })) {
    if ($jsonBuild.Switchable -eq "True") {
        $null = $commentStringBuilder.AppendLine("$($jsonBuild.Type)`r`nSWITCHABLE`r`n`r`n$($jsonBuild.Comment)")
    }
    else {
        $null = $commentStringBuilder.AppendLine("$($jsonBuild.Type)`r`n`r`n$($jsonBuild.Comment)")
    }
    foreach ($inRule in $jsonBuild.Destination) {
         $null = $inboundStringBuilder.AppendLine("$($inRule.Protocol)://$($inRule.Domain)$($inRule.Path)`r`nPoint to $($inRule.Host)`r`n`r`n" )
     }
}

$inboundEndpoint = $inboundStringBuilder.ToString()
$inboundComment = $commentStringBuilder.ToString()

And to $OFS:

$OFS = "`r`n"
# Other code that uses it, foreach pipelines etc
# -ComObject example:
$Table.cell(($a + 2), 1).range.text = $integration.Rule | where { $_.Type -eq "Inbound" } | foreach { $_.SourceIP } | Sort-Object | Get-Unique | Out-String

#OfficeIMO:
$table.Rows[($a + 2)].Cells[0].Paragraphs[0].Text = $integration.Rule | where { $_.Type -eq "Inbound" } | foreach { $_.SourceIP } | Sort-Object | Get-Unique | Out-String

Remove-Variable OFS

I tried adding .AddParagraphBefore/AfterSelf(), but it just adds one before/after the blob of text that gets put into the cell, not between all of it.

This is text that goes into cells all over the table, but since it's multiple objects being passed from the JSON to one cell, it all gets written to one line inside the cell. The above code works with -ComObject Word.Application - I know it doesn't matter much, just as an input.

PrzemyslawKlys commented 2 years ago

Adding "rn" or anything like that won't work because it's not doing anything in the Text.

image

I've now tested 2 solutions. One is something I've added just now, the other one is something that's builtin and it seems to work.

image

In other words you were not working with paragraphs you have added, but with first paragraph of each cell. When you do AddParagraphAfterSelf or AddParagraphBefore() you need to make sure you are updating variable with new paragraph as new paragraph is returned.

image

PrzemyslawKlys commented 2 years ago

You can also do this:

image

PrzemyslawKlys commented 2 years ago

Also keep in mind the AddBreak and AddParagraph will have a different behavior. If what you want is AddBreak then we need to "update the DLL" in this project and release new version, but the idea is the same.

GhostyIs1337 commented 2 years ago

Interesting approach, I'll have to play around with it.

However, I think AddBreak() would be more inline with what I'm trying to achieve, especially since I have to remove some empty rows and looking through empty paragraphs is sort of annoying to determine throughout the whole table which are actually empty and which aren't. :)

Keeping the .dll up to date with the main one, especially on major changes probably wouldn't be a bad idea either - but that is entirely up to you, of course.

edit: Actually, nevermind, I looked at how -ComObject Word.Application handles \r\n, and it looks like it does it as end of paragraph, i.e. AddParagraphAfterSelf(). Interesting.

image

PrzemyslawKlys commented 2 years ago

I guess it would be possible to write that logic that if you use "\r\n" in text it should add new paragraph automatically.

GhostyIs1337 commented 2 years ago

Something to look at for sure. :)

v-bulynkin commented 1 year ago

How to add not a paragraph but a new line in the same paragraph? It is indicated by the Enter symbol below and can be typed by Shift+Enter keys.

изображение

PrzemyslawKlys commented 1 year ago
$paragraph2 = $document.AddParagraph("Adding paragraph2 with some text and pressing SHIFT+ENTER");
paragraph2.AddBreak();
paragraph2.AddText("Continue1");
paragraph2.AddBreak();
paragraph2.AddText("Continue2");

As shown in here: https://github.com/EvotecIT/OfficeIMO/issues/37

v-bulynkin commented 1 year ago

Thank you! However, I don't clearly understand how to combine it with the syntax

New-OfficeWordText -Document $doc -Alignment Center -Text "Adding paragraph2 with some text and pressing SHIFT+ENTER"

What if I need to make one line bold or italic if I use paragraph2.AddText("Continue1");?

PrzemyslawKlys commented 1 year ago
$Document = New-OfficeWord -FilePath $PSScriptRoot\Documents\BasicDocument.docx

New-OfficeWordText -Document $Document -Text 'This is a test, very big test ', 'and this should be bold' -Bold $null, $true -Underline Dash, $null

New-OfficeWordText -Document $Document -Text 'This is a test, very big test', 'ooops' -Color Blue, Gold -Alignment Right

$Paragraph = New-OfficeWordText -Document $Document -Text 'Centered' -Color Blue, Gold -Alignment Center -ReturnObject
$Paragraph = $Paragraph.AddBreak()
New-OfficeWordText -Document $Document -Text ' Attached to existing paragraph', ' continue' -Paragraph $Paragraph -Color Blue

Save-OfficeWord -Document $Document -Show

This should work. So you have to use ReturnObject and you can mix and match ways to build things. You can also just work with the native way

$Document = New-OfficeWord -FilePath $PSScriptRoot\Documents\BasicDocument.docx

New-OfficeWordText -Document $Document -Text 'This is a test, very big test ', 'and this should be bold' -Bold $null, $true -Underline Dash, $null

New-OfficeWordText -Document $Document -Text 'This is a test, very big test', 'ooops' -Color Blue, Gold -Alignment Right

$Paragraph = New-OfficeWordText -Document $Document -Text 'Centered' -Color Blue, Gold -Alignment Center -ReturnObject
$Paragraph = $Paragraph.AddBreak()
$Paragraph = New-OfficeWordText -Document $Document -Text ' Attached to existing paragraph', ' continue' -Paragraph $Paragraph -Color Blue -ReturnObject
$Paragraph.Bold = $true
$Paragraph = $Paragraph.SetItalic().AddText("More txt").SetBold()
$Paragraph = $Paragraph.AddText("Even more text").AddBreak()
$Paragraph.AddText("Mix and match").SetBold().SetItalic()
$Paragraph = $Paragraph.SetUnderline([DocumentFormat.OpenXml.Wordprocessing.UnderlineValues]::Dash)
Save-OfficeWord -Document $Document -Show

Normally I guess we should add New-OfficeWordBreak and have a nice little helper function, but building both OfficeIMO and PSWriteHTML and all other modules doesn't give me much time.

v-bulynkin commented 1 year ago

Works great, thank you very much for the explanation!