I’m trying to add a watermark to every page of a document. Some pages have tables and I need watermark to appear on top of the tables. The code below gives me a nice watermark on the first page if a put it just after I create the document. If I put it at the end of document code I get a bunch of watermarks on the first page but nothing on the subsequent pages.
The code found here:
https://forum.aspose.com/t/add-watermark-to-every-page-in-word-document-make-watermark-appear-on-front-of-images-set-z-order-using-c-java/209278/6
mangles my table on the first page and doesn’t give me a watermark on subsequent pages…
code:
MemoryStream outputStream = new MemoryStream();
using (MemoryStream memoryStream = new MemoryStream())
{
Document doc = new Document(memoryStream);
DocumentBuilder builder = new DocumentBuilder(doc);
.
.
.
// Determine the maximum ZOrted of shapes in the document.
int zOrder = 0;
var shapes = doc.GetChildNodes(NodeType.Shape, true);
foreach (Shape s in shapes)
{
zOrder = Math.Max(zOrder, s.Count); //s.getZOrder());
}
zOrder++;
// Create a watermark shape.
Shape watermark = new Shape(doc, ShapeType.TextPlainText);
// watermark.Name("WaterMark");
// Set up the text of the watermark.
watermark.TextPath.Text = "DRAFT";
watermark.TextPath.Bold = true;
watermark.TextPath.Size = 100;
watermark.TextPath.FontFamily = "Arial";
watermark.Width = 500;
watermark.Height = 100;
watermark.FillColor = Color.LightGray;
watermark.StrokeColor = Color.LightGray;
watermark.Fill.Opacity = 0.5;
// Text will be directed from the bottom-left to the top-right corner.
watermark.Rotation = 45;
// Place the watermark in the page center.
watermark.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
watermark.RelativeVerticalPosition = RelativeVerticalPosition.Page;
watermark.WrapType = WrapType.None;
watermark.HorizontalAlignment = HorizontalAlignment.Center;
watermark.VerticalAlignment = VerticalAlignment.Center;
watermark.ZOrder = zOrder;
// Get paragraphs in the document.
var paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
LayoutCollector layoutCollector = new LayoutCollector(doc);
int pageToInsert = 1;
foreach (Paragraph para in paragraphs)
{
// Process only paragraphs in the main body.
if (para.GetAncestor(NodeType.Body) == null)
continue;
int paraPage = layoutCollector.GetEndPageIndex(para);
// if (paraPage == pageToInsert)
if (paraPage <= 50)
{
pageToInsert++;
// para.AppendChild(watermark.DeepClone(true));
para.AppendChild(watermark.Clone(true));
}
}
.
.
doc.Save(outputStream, SaveFormat.Docx);
What am I doing wrong?
Thank you.
@dmurphy6 Normally, watermark is inserted into the documents header, which is under the main document’s body content. This is the same behavior as in MS Word when you insert a watermark. So opaque content will overlap the watermark.
You can overcome this by inserting “watermark” like shape in front of text. To insert a watermark in front of the content you have to insert it in the main body, but in this case you will have to insert it on each page of the document, just like you do in the provided code. LayoutCollector can help you with this. Please try using the following code:
Document doc = new Document("C:\\Temp\\in.docx");
// Determine the maximum ZOrted of shapes in the document.
int zOrder = 0;
foreach (Shape s in doc.GetChildNodes(NodeType.Shape, true))
{
zOrder = Math.Max(zOrder, s.ZOrder);
}
zOrder++;
// Create a watermark shape.
Shape watermark = new Shape(doc, ShapeType.TextPlainText);
watermark.Name = "WaterMark";
// Set up the text of the watermark.
watermark.TextPath.Text = "In Front Watermark";
watermark.TextPath.Bold = true;
watermark.TextPath.Size = 100;
watermark.TextPath.FontFamily = "Arial";
watermark.Width = 500;
watermark.Height = 100;
watermark.Fill.ForeColor = Color.LightGray;
watermark.StrokeColor = Color.LightGray;
// Text will be directed from the bottom-left to the top-right corner.
watermark.Rotation = 45;
// Place the watermark in the page center.
watermark.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
watermark.RelativeVerticalPosition = RelativeVerticalPosition.Page;
watermark.WrapType = WrapType.None;
watermark.HorizontalAlignment = HorizontalAlignment.Center;
watermark.VerticalAlignment = VerticalAlignment.Center;
watermark.ZOrder = zOrder;
LayoutCollector layoutCollector = new LayoutCollector(doc);
int pageToInsert = 1;
foreach (Paragraph para in doc.GetChildNodes(NodeType.Paragraph, true))
{
// Process only paragraphs in the main body.
if (para.GetAncestor(NodeType.Body) == null)
continue;
int paraPage = layoutCollector.GetEndPageIndex(para);
if (paraPage == pageToInsert)
{
pageToInsert++;
para.AppendChild(watermark.Clone(true));
}
}
doc.Save("C:\\Temp\\out.docx");
// Since we have used LayoutCollector, Aspose.Words cached layout of the document
// and the modifications we have made are not in the cache.
// Update page layout to reflect the changes in the output fixed Page formats.
doc.UpdatePageLayout();
doc.Save("C:\\Temp\\out.pdf");
If the problem still persists, please attach your input and output documents here for our reference.
asposeEval.docx (10.3 KB)
The updated code seems to mess up my formatting. The cell widths in my table on page one are not what I was trying to set them to.
Text on page two is centered and it should be left justified.
Watermark on page one is too far to left. Watermark looks great on page 3 but there should only be two pages in the document?!
@dmurphy6 Could you please attach your input document here for testing? We will check it and provide you more information.
Regarding the position of watermark on the first page. The paragraph where shape is inserted is inside table cell, special rules are applied to shapes inside table cells. So the position is shifted. You can set the following property:
watermark.IsLayoutInCell = false;
And optimize document for older version of MS Word since this option does not work in new versions:
doc.CompatibilityOptions.OptimizeFor(MsWordVersion.Word2010);
Alexey,
Turned out I needed the following code to fix my table:
pageOneTable.PreferredWidth = PreferredWidth.FromPoints(470);
builder.EndTable();
pageOneTable.AutoFit(AutoFitBehavior.FixedColumnWidths);
Thanks again,
Dave
1 Like
@dmurphy6 It is perfect that you managed to resolve the problem. Please feel free to ask in case of any issues. We are always glad to help you.