EvotecIT / OfficeIMO

Fast and easy to use cross-platform .NET library that creates or modifies Microsoft Word (DocX) and later also Excel (XLSX) files without installing any software. Library is based on Open XML SDK
MIT License
286 stars 50 forks source link

Questions around TextBox #185

Closed TopperDEL closed 8 months ago

TopperDEL commented 9 months ago

Sorry to spam you with issues today. :)

I have some questions:

Thank you for your time and effort on this!

PrzemyslawKlys commented 9 months ago

Huh? What do you mean?

TopperDEL commented 9 months ago

See here a sample in Word:

https://github.com/EvotecIT/OfficeIMO/assets/1833242/e2daafc2-d905-467d-b467-27cd77999c3f

PrzemyslawKlys commented 9 months ago
$varValue = $Document.AddTextbox("Text");
$varValue.WordParagraph.Text =" ChangeText"
$varvalue.WordParagraph.Color = xxx

I am not sure I understand, but Textbox has WordParagraph linked to it and it's responsisble how those colors/data looks like.

PrzemyslawKlys commented 9 months ago

Maybe defaults couldd be changed.

TopperDEL commented 9 months ago

See here how the TextBox "gets pushed" to the end of the document if the flowting text before it gets larger.

https://github.com/EvotecIT/OfficeIMO/assets/1833242/0d5b4a84-b332-48bb-9921-a1d92a970fab

PrzemyslawKlys commented 9 months ago

You need to change Position of it and to what it's relative to? Maybe the defaults are relative to Paragraph?

TopperDEL commented 9 months ago
$varValue = $Document.AddTextbox("Text");
$varValue.WordParagraph.Text =" ChangeText"
$varvalue.WordParagraph.Color = xxx

I am not sure I understand, but Textbox has WordParagraph linked to it and it's responsisble how those colors/data looks like.

Maybe word recognizes somethin special within? On right click on the blue text it lets me "Remove content control" ("Inhaltssteuerelement entfernen" in german).

TopperDEL commented 9 months ago

You need to change Position of it and to what it's relative to? Maybe the defaults are relative to Paragraph?

So maybe I should add the TextBox on a "Section" or the page itself instead?

PrzemyslawKlys commented 9 months ago

It can be on the page, but $varValue has PositionRelativeTo or similar property which you can change.

TopperDEL commented 9 months ago

Hm, this is my code:

var textBox = document.AddTextBox(partText);
textBox.RelativeWidthPercentage = 0;
textBox.RelativeHeightPercentage = 0;
textBox.HeightCentimeters = part.Height / 10;
textBox.WidthCentimeters = part.Width / 10;
textBox.HorizontalPositionRelativeFrom = DocumentFormat.OpenXml.Drawing.Wordprocessing.HorizontalRelativePositionValues.Page;
textBox.VerticalPositionRelativeFrom = DocumentFormat.OpenXml.Drawing.Wordprocessing.VerticalRelativePositionValues.Page;
textBox.HorizonalPositionOffsetCentimeters = part.Left / 10;
textBox.VerticalPositionOffsetCentimeters = part.Top / 10;

The TextBox still is being moved when the floating text gets larger.

PrzemyslawKlys commented 9 months ago

how would you make it stick when doing it manually?

TopperDEL commented 9 months ago

It seems my understanding of Word is wrong. I thought this should do the trick:

image

Basically bring the TextBox "In front of the text" so that it is independent of the normal text flow.

PrzemyslawKlys commented 9 months ago

ye, so this WordTextBox needs extension for that. I believe it's hardcoded to single value. Unfortunetly I won't have time for a week to take a look at it.

From what I see when you change it to vor den text it actually adds WrapNone to anchor.

image

In my code it has wraptopbottom

image

So this would need additional get/set logic to look for those "Wrap" types and add them or remove them on demand.

TopperDEL commented 9 months ago

I'm still trying to accomplish what I need with word itself. It is not that trivial as it seems. Basically I want to place some text in the first page only and at specific locations. Maybe I first need to add the floating text and afterwards add my fixed textboxes to the first page? I'm confused.

Don't worry about your timeframe! There is not immediate need to adjust anything. Thank you, though!

PrzemyslawKlys commented 9 months ago

Maybe Relative to margin, rather than to page? Dunno, try in Word itself and once you have that ready you can see how the code looks like in Open XML SDK 2.5 Productivity Tool and see what's missing.

TopperDEL commented 9 months ago

Ok, I've sorted a bit. Where I was wrong: I have to anchor or add the textboxes within the header/footer. Then they are at a specific location on a page. I still have the issue with the TextBox-Text being some kind of "variable" within word (rendered as blue text). But I will tackle this later. And come back to here.

TopperDEL commented 9 months ago

Back at work. :) So, I need to add a TextBox to the Header and Footer. But those do not have corresponding AddTextBox()-Methods. Would ypu be able to add them without much effort? I still do not quite understand how your library works internally - I hope that I can help you out adding features like this.

PrzemyslawKlys commented 8 months ago

It should be fairly easy to add, mostly copy paste. As the textbox attaches between paragraphs so mostly similar to other Add commands. I will be back at work next week. If you figure it out..., if not i'll fix it

TopperDEL commented 8 months ago

Just tried a bit but was unsuccessfull. I am confused with the types you have (like WordParagraph) and the types from the OpenXml-library (like Paragraph). I can create a TextBox and a TextBoxContent and add it to your WordDocument - but it does not Show up. I think I need to add my "self created" paragraph to an internal list of your paragraphs? Will check again tomorrow.

PrzemyslawKlys commented 8 months ago

I've made a simple PR showing this functionality. I don't have proper internet/my workstation to work on this, but it does add it to header/footer and you should be able to play with it there (linked to this issue)

TopperDEL commented 8 months ago

You're awesom! That PR helped alot and I now have a much better understanding of how everything works. I've added some features I needed along the way.

What still confuses me a bit is how you wrap the underlying OpenXML-classes. E.g. if you look at my PR #188 - I've added a feature to add multiple runs and breaks from the text provided. But this is just a quick workaround. You have a similar logic in WordParagraph.PrivateMethos.cs on a WordParagraph. But I cannot use it here because the WordParagraph on a WordTextBox is just a "on-the-fly"-wrapper around the first run of the textbox. Maybe I'm still missing something - but it is not always clear when you have an own class for something and when you use the OpenXML-types. E.g. my new TextBodyProperties-Property on WordTextBox feels wrong as it gives access to the underlying OpenXML-Type. Should I add dedicated properties for that? But wouldn't that make it just more complex to add every single propertie of every part of all elements?

PrzemyslawKlys commented 8 months ago

To be honest I do it on my best guess. I use openxml types if it's pretty clear conversion, but when for example wrap/nowrap/and few other options means you need to add internally few other things I would go create something internal.

For your specific use case I guess it would make sense to create multiple properties as long as those make sense in exposing them. I usually expose those that I use, but when you use multiple others ...

Also I believe expanding AddTextbox method with other properties makes sense like position, and other settings that usually means you need to change them anyways.

I'm experimenting as I go ;)

PrzemyslawKlys commented 8 months ago

Keep in mind that NoWrap or Wrap are just one of X number of options available (as per your screenshot). So this can't be a bool, but more likely an enum that causes different code changes. Take a look at WordImage. I believe it has similar code in this regards.