Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HeadingType is not applied when using Load() #245

Open
PrzemyslawKlys opened this issue Jul 19, 2018 · 22 comments
Open

HeadingType is not applied when using Load() #245

PrzemyslawKlys opened this issue Jul 19, 2018 · 22 comments

Comments

@PrzemyslawKlys
Copy link
Contributor

PrzemyslawKlys commented Jul 19, 2018

While below code is powershell it uses your .NET. Essentially when you use .Load(Path) and apply HeaderStyle it's not saved in final document making TOC useless. It behaves as expected on .Create(Path)

Import-Module PSWriteWord -Force

$FilePath = "$Env:USERPROFILE\Desktop\PSWriteWord-Example-TableOfContent3.docx"

$WordDocument = New-WordDocument -FilePath $FilePath
$Toc = Add-WordTOC -WordDocument $WordDocument -Title 'Table of content' -HeaderStyle Heading2
Add-WordSection -WordDocument $WordDocument -PageBreak
Add-WordText -WordDocument $WordDocument -Text 'This is my first title' -HeadingType Heading1
Add-WordSection -WordDocument $WordDocument -PageBreak
Add-WordText -WordDocument $WordDocument -Text 'This is my second title' -HeadingType Heading1 -Color Red -CapsStyle caps
Add-WordSection -WordDocument $WordDocument -PageBreak
Add-WordText  -WordDocument $WordDocument -Text 'This is my third title' -HeadingType Heading2 -Italic $true -Bold $true
Save-WordDocument $WordDocument

### Start Word with file
Invoke-Item $FilePath
Import-Module PSWriteWord -Force

$FilePath = "$Env:USERPROFILE\Desktop\PSWriteWord-Example-TableOfContent7.docx"
$FilePathTemplate = "$PSScriptRoot\Templates\WordTemplate.docx"

$WordDocument = Get-WordDocument -FilePath $FilePathTemplate
$Toc = Add-WordTOC -WordDocument $WordDocument -Title 'Table of content' -HeaderStyle Heading2
Add-WordSection -WordDocument $WordDocument -PageBreak
Add-WordText -WordDocument $WordDocument -Text 'This is my first title' -HeadingType Heading1
Add-WordSection -WordDocument $WordDocument -PageBreak
Add-WordText -WordDocument $WordDocument -Text 'This is my second title' -HeadingType Heading1 -Color Red -CapsStyle caps
Add-WordSection -WordDocument $WordDocument -PageBreak
Add-WordText  -WordDocument $WordDocument -Text 'This is my third title' -HeadingType Heading2 -Italic $true -Bold $true

$WordDocument.Xml
Save-WordDocument $WordDocument -FilePath $FilePath

### Start Word with file
Invoke-Item $FilePath

To reproduce it in pseudo code

Load
Create few Paragraphs
Add text to each paragraph
Make it Heading1 or Heading2
Save
Open

When checking:
Document.Paragraphs.StyleName

Heading2
TOC1
Normal
Normal
Heading1
Normal
Heading1
Normal
Heading2
Normal
Heading2
TOC1
Normal
Normal
Heading1
Normal
Heading1
Normal
Heading2

So comparison is almost identical but still save doesn't cover this. Replacing Load with Create - everything works again. I'm using https://github.com/EvotecIT/PSWriteWord/blob/master/Examples/Templates/WordTemplate.docx as a template but shouldn't really matter I guess.

@XceedBoucherS
Copy link
Collaborator

Hi,

We cannot reproduce this in v1.2.
Here's the sample we use :
` var doc = DocX.Load( "WordTemplate.docx" );
doc.InsertParagraph( "Paragraph2" ).Heading( HeadingType.Heading1 );
doc.InsertParagraph( "Paragraph3" ).Heading( HeadingType.Heading2 );
doc.SaveAs("output.docx");

  var doc2 = DocX.Load( "output.docx" );
  var paragraphCount = doc2.Paragraphs.Count;
  Debug.Assert( doc2.Paragraphs[ paragraphCount - 1 ].StyleName == HeadingType.Heading2.ToString() );
  Debug.Assert( doc2.Paragraphs[ paragraphCount - 2 ].StyleName == HeadingType.Heading1.ToString() );`

Are we missing anything ?
Thank you.

@PrzemyslawKlys
Copy link
Contributor Author

PrzemyslawKlys commented Jul 25, 2018

Yes. I use $Paragraph.StyleName = $HeadingType instead of the way you do. I guess I'll switch to your approach if it works. So in C# it would be

var doc = DocX.Load( "WordTemplate.docx" );
doc.InsertParagraph( "Paragraph2" ).StyleName = HeadingType.Heading1;
doc.InsertParagraph( "Paragraph3" ).StyleName = HeadingType.Heading2;
doc.SaveAs("output.docx");

More or less. And what I actually do in code is

var doc = DocX.Load( "WordTemplate.docx" );
var paragraph = doc.InsertParagraph( "Paragraph2" );
var paragraph1 = doc.InsertParagraph( "Paragraph3" );
paragraph.StyleName = HeadingType.Heading2;
paragraph1.StyleName = HeadingType.Heading1;
doc.SaveAs("output.docx");

@PrzemyslawKlys
Copy link
Contributor Author

PrzemyslawKlys commented Jul 25, 2018

And maybe I'm using it wrong but I don't see... Heading property for Paragraph

image

But I do see it in examples

 public static void Heading()
    {
      Console.WriteLine( "\tHeading()" );

      // Create a document.
      using( DocX document = DocX.Create( ParagraphSample.ParagraphSampleOutputDirectory + @"Heading.docx" ) )
      {
        // Add a title.
        document.InsertParagraph( "Heading types" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center;

        var headingTypes = Enum.GetValues( typeof( HeadingType ) );

        foreach( HeadingType heading in headingTypes )
        {
          // Set a text containing the current Heading type.
          var text = string.Format( "This Paragraph is using \"{0}\" heading type.", heading.EnumDescription() );
          // Add a paragraph.
          var p = document.InsertParagraph().AppendLine( text );
          // Set the paragraph's heading type.
          p.Heading( heading );
        }

        document.Save();
        Console.WriteLine( "\tCreated: Heading.docx\n" );
      }
    }

So I'll verify why I don't see it. Anyways I use it via StyleName instead of Heading property.

@XceedBoucherS
Copy link
Collaborator

If you want to use it your way, you should use it this way :

`var doc = DocX.Load( "WordTemplate.docx" );
//doc.InsertParagraph( "Paragraph2" ).Heading( HeadingType.Heading1 );
//doc.InsertParagraph( "Paragraph3" ).Heading( HeadingType.Heading2 );
var paragraph = doc.InsertParagraph( "Paragraph2" );
var paragraph1 = doc.InsertParagraph( "Paragraph3" );
paragraph.StyleName = HeadingType.Heading1.ToString();
paragraph1.StyleName = HeadingType.Heading2.ToString();
doc.SaveAs("output.docx");

  var doc2 = DocX.Load( "output.docx" );
  var paragraphCount = doc2.Paragraphs.Count;
  Debug.Assert( doc2.Paragraphs[ paragraphCount - 1 ].StyleName == HeadingType.Heading2.ToString() );
  Debug.Assert( doc2.Paragraphs[ paragraphCount - 2 ].StyleName == HeadingType.Heading1.ToString() );`

Paragraph only contains a StyleName property, which is a string. It doesn't contain a Heading property.

@PrzemyslawKlys
Copy link
Contributor Author

Well I do have that

image

Yet the result is:

image

@PrzemyslawKlys
Copy link
Contributor Author

In c#

        public static void InsertTableOfContentWithReference1()
        {
            Console.WriteLine("\tInsertTableOfContentWithReference()");

            // Create a document.
            using (DocX document = DocX.Load(TableOfContentSample.TableOfContentSampleOutputDirectory + @"WordTemplate.docx"))
            {
                var paragraph = document.InsertParagraph("Paragraph2");
                var paragraph1 = document.InsertParagraph("Paragraph3");
                paragraph.StyleName = HeadingType.Heading1.ToString();
                paragraph1.StyleName = HeadingType.Heading2.ToString();

                document.SaveAs(TableOfContentSample.TableOfContentSampleOutputDirectory + @"InsertTableOfContentWithReference1.docx");
                Console.WriteLine("\tCreated: InsertTableOfContentWithReference.docx\n");
            }
        }

Notice how it's not set

image

And Create


        public static void InsertTableOfContentWithReference1()
        {
            Console.WriteLine("\tInsertTableOfContentWithReference()");

            // Create a document.
            using (DocX document = DocX.Create(TableOfContentSample.TableOfContentSampleOutputDirectory + @"InsertTableOfContentWithReference1.docx"))
            //using (DocX document = DocX.Load(TableOfContentSample.TableOfContentSampleOutputDirectory + @"WordTemplate.docx"))
            {
                var paragraph = document.InsertParagraph("Paragraph2");
                var paragraph1 = document.InsertParagraph("Paragraph3");
                paragraph.StyleName = HeadingType.Heading1.ToString();
                paragraph1.StyleName = HeadingType.Heading2.ToString();

                document.SaveAs(TableOfContentSample.TableOfContentSampleOutputDirectory + @"InsertTableOfContentWithReference1.docx");
                Console.WriteLine("\tCreated: InsertTableOfContentWithReference.docx\n");
            }
        }

image

Diffence is just Create vs Load.

@PrzemyslawKlys
Copy link
Contributor Author

And your code doesn't give better results either:

        public static void InsertTableOfContentWithReference1()
        {
            Console.WriteLine("\tInsertTableOfContentWithReference()");

            // Create a document.
            //using (DocX document = DocX.Create(TableOfContentSample.TableOfContentSampleOutputDirectory + @"InsertTableOfContentWithReference1.docx"))
            using (DocX document = DocX.Load(TableOfContentSample.TableOfContentSampleOutputDirectory + @"WordTemplate.docx"))
            {
                var paragraph = document.InsertParagraph("Paragraph2").Heading(HeadingType.Heading1);
                var paragraph1 = document.InsertParagraph("Paragraph3").Heading(HeadingType.Heading1);
               // paragraph.StyleName = HeadingType.Heading1.ToString();
               // paragraph1.StyleName = HeadingType.Heading2.ToString();

                document.SaveAs(TableOfContentSample.TableOfContentSampleOutputDirectory + @"InsertTableOfContentWithReference1.docx");
                Console.WriteLine("\tCreated: InsertTableOfContentWithReference.docx\n");
            }
        }

Headings are not set.

@XceedBoucherS
Copy link
Collaborator

Hello,
Thank you for the precision.

When creating a document, the style used will be the the default styles (including Heading1, Heading2...), but when loading a document, its defined styles will be used.
In this case, WordTemplate.docx do not contains the HeadingX styles.

We will investigate on this.

@Matdegraye
Copy link

Hello
After investigations, I come to the same conclusion as Klys.
Anyway thanks for the great job done, & I am looking forward for the fix.

@PrzemyslawKlys
Copy link
Contributor Author

I worked around it by creating empty doc, saving and then adding my flavors making it my template. Works

@ruizdidier
Copy link

Hi @PrzemyslawKlys , i'm experiencing the same issue and would be very helpful if you can be more detailed on your solution proposal.

Thanks in advance

@PrzemyslawKlys
Copy link
Contributor Author

Just create an empty doc with DocX and work from there. It will have proper format that is required.

@ruizdidier
Copy link

Just create an empty doc with DocX and work from there. It will have proper format that is required.

@PrzemyslawKlys I tried, but if i make some change on it using Office like edit the header it keep doing the same. I have to put a logo just like u show on your screenshots, but i cant find a way to put an image as a header using DocX

@PrzemyslawKlys
Copy link
Contributor Author

What I did is exactly as I said:

  1. Empty document with DocX (well PSWriteWord in PowerShell)
  2. Open it up in Word
  3. Go into headers, pasted an image of logo (actually it's A4 sized logo so it covers full page along with footer as 1 image.
  4. Saved document
  5. Using that document as Template for things I do in DocX (PSWriteWord to be exact)

@ruizdidier
Copy link

Thanks for your replay, i followed your suggestion but i changed the editor for the Doc Drive downloading as a .docx and it worked perfectly.

I found that if you save in latest version of Word it changes the schemas from 2006 to 2015 or later in the "document.xml" and i think that's the problem, because trying with other editors they use http://schemas.openxmlformats.org/markup-compatibility/2006

@mastertnt
Copy link

Hello everybody,
Is there a planned version to solve this issue ? The proposed workaround cannot be applied inmy case.
Regards,

@mastertnt
Copy link

After some investigations, the property "Stylename" is a little bit confusing. It should be "Styleid", the element name in the schema is not the same thing for a style.

In my point of view, the easiest way could be to retrieve styles by alias and to apply the retrieved style id on a property named "Styleid"

@XceedBoucherS
Copy link
Collaborator

Hi mastertnt,
This changed is already done. In the future relase v1.8, "StyleName" is considered obsolete while "StyleId" is the new property to use.
Thank you

@mastertnt
Copy link

mastertnt commented Apr 28, 2020

Hi,

Thanks for the answer.

If you use StyleId, the Load function has no trouble. The difficulty is to know the correct StyleId (the aliases displayed in Word seems more natural) or i don't the way to retrieve it from the API.

Regards,

@XceedBoucherS
Copy link
Collaborator

Hi,
You are right, these are not easy to know.
Keep in mind that styleIds don't have spaces and use Camel case. So "Heading 1" will have the styleId "Heading1", "Normal" will have styleId "Normal"....

@mastertnt
Copy link

Hi,

Thanks for the precision, i have already seen this. I use a french template and also all the special characters present in Latin1 character set are removed for example, "Référence" will have styleId "Rfrence".

For other languages (like chinese), i don't know if it is possible to infer the styleId.

Regards,

@XceedBoucherS
Copy link
Collaborator

Hi,

For Heading types, you can always use the Paragraph.Heading() method, which take in parameter a HeadingType. Therefor, you don't have to use the styleId, at least for the heading types.

In v1.8, you will also have access to a static method in Document called "GetParagraphStyleIdFromStyleName" which will take in argument a styleName and return the corresponding styleId.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants