Blank first page with PDF generation

I am having an issue with a blank first page when documents are rendered to a PDF. This only occurs if an image is the first item on the page. All other documents with just text render fine. We have a valid license and have the most current version of the software.

Hi,

Thanks for your inquiry. Please attach your input Word document and output PDF file showing the undesired behavior here for testing. We will investigate the issue on our end and provide you more information.

Best regards,

Thank you for getting back to me. Below is a snippet of code that will reproduce the error. I have also attached two word docs that we append and the undesirable PDF output following a save.

Aspose.Words.License lic = new Aspose.Words.License();
lic.SetLicense("Aspose.Words.lic");
var doc = new Document();
var docParent = new Document("C:\\RichTextParent.doc");
var docChild = new Document("C:\\RichTextChild.doc");
doc.AppendDocument(docParent, ImportFormatMode.KeepSourceFormatting);
doc.AppendDocument(docChild, ImportFormatMode.KeepSourceFormatting);
doc.Save("C:\\Finaldoc.doc");
doc.Save("C:\\Finaldoc.pdf");

Thank you again for your help.

Hi,

Thanks for your inquiry. You need to remove all content from the “doc” object before appending “docParent” and “docChild” documents to it. Please see the first example in the following article:
https://docs.aspose.com/words/java/insert-and-append-documents/

I hope, this helps.

Best regards,

Hello,
Thank you for your response. Unfortunately, in our actual code we do things a little differently. We do not use the append method and simply removing all of the children from an initial blank document does not seem to work. I have now placed code below that more closely reflects how our environment is set up. We still receive the initial blank first page with content pushed to the second page. I have attached the two test documents again so that you can recreate the issue with our code.
Thank you

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Aspose.Words;
using Aspose.Words.Fields;
using System.Text.RegularExpressions;
namespace TestOfAsposeIssue
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            var lic = new License();
            lic.SetLicense("Aspose.Words.lic");

            DocSetupAndCreate();
        }

        private void DocSetupAndCreate()
        {

            var mDocument = new Document("C:\\RichTextParent.doc");

            var mergeField = new WordMergeField()
            {
                Name = "Rich Text Merge|DM",
                RawFieldName = "Rich Text Merge|DM"
            };

            var richTextDoc = new Document("C:\\RichTextChild.doc");

            // Find parent nodes of merge fields and insert the rich text document
            var locator = new MergeFieldLocator(mergeField);
            mDocument.Accept(locator);
            foreach (Node node in locator.MergeFieldParentNodes)
            {
                //_log.DebugFormat("Merging field '{0}', locale {1}, into node '{2}'", mergeField.Name, mergeField.LocaleId, node.GetText());
                InsertDocument(node, richTextDoc);
            }
            mDocument.Save("C:\\Aspose-3-27.pdf");
        }

        /// 

        /// Inserts content of the external document after the specified node.
        /// Section breaks and section formatting of the inserted document are ignored.
        /// 

        /// Node in the destination document after which the content 
        /// should be inserted. This node should be a block level node (paragraph or table).
        /// The document to insert.
        internal static void InsertDocument(Node insertAfterNode, Document srcDoc)
        {
            // NOTE: this code is adapted from the Aspose Programmer's Guide
            // Make sure that the node is either a pargraph or table.
            if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) &
            (!insertAfterNode.NodeType.Equals(NodeType.Table)))
            {
                throw new ArgumentException("The destination node should be either a paragraph or table.");
            }
            // We will be inserting into the parent of the destination paragraph.
            CompositeNode dstStory = insertAfterNode.ParentNode;
            // This object will be translating styles and lists during the import.
            NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.UseDestinationStyles);
            // Loop through all sections in the source document.
            foreach (Aspose.Words.Section srcSection in srcDoc.Sections)
            {
                // Loop through all block level nodes (paragraphs and tables) in the body of the section.
                foreach (Node srcNode in srcSection.Body)
                {
                    // Let's skip the node if it is a last empty paragarph in a section.
                    if (srcNode.NodeType.Equals(NodeType.Paragraph))
                    {
                        Aspose.Words.Paragraph para = (Aspose.Words.Paragraph)srcNode;
                        if (para.IsEndOfSection && !para.HasChildNodes)
                            continue;
                    }
                    // This creates a clone of the node, suitable for insertion into the destination document.
                    Node newNode = importer.ImportNode(srcNode, true);
                    // Insert new node after the reference node.
                    dstStory.InsertAfter(newNode, insertAfterNode);
                    insertAfterNode = newNode;
                }
            }
        }

        /// 

        /// Used to find merge fields by name as Aspose.Words.Node objects
        /// 

        private class MergeFieldLocator : DocumentVisitor
        {
            private readonly WordMergeField mMergeField;
            private bool mInParentMergeField;
            readonly List mParentNodeList = new List();
            public MergeFieldLocator(WordMergeField mergeField)
            {
                mMergeField = mergeField;
            }
            public List MergeFieldParentNodes
            {
                get
                {
                    return mParentNodeList;
                }
            }
            public override VisitorAction VisitRun(Run run)
            {
                if (mInParentMergeField && mMergeField.Matches(run.Text))
                {
                    mParentNodeList.Add(run.ParentNode);
                }
                return base.VisitRun(run);
            }
            public override VisitorAction VisitFieldStart(FieldStart fieldStart)
            {
                if (fieldStart.FieldType == FieldType.FieldMergeField)
                {
                    mInParentMergeField = true;
                }
                return base.VisitFieldStart(fieldStart);
            }
            public override VisitorAction VisitFieldSeparator(FieldSeparator fieldSeparator)
            {
                mInParentMergeField = false;
                return base.VisitFieldSeparator(fieldSeparator);
            }
            public override VisitorAction VisitFieldEnd(FieldEnd fieldEnd)
            {
                mInParentMergeField = false;
                return base.VisitFieldEnd(fieldEnd);
            }
        }
        public class WordMergeField
        {
            // private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
            private static readonly Regex mRawFieldRegex = new Regex(@"^(.*?)\[(.*)\]");
            private static readonly Regex mParentTextRegex = new Regex("\\\"(.*?)\\\"");
            private const int DefaultLocaleId = 1;
            private const int DefaultBlankLength = 0;
            private static readonly string[] FullLocaleNames = new[] {
                "english",
                "spanish"
                };
            private static readonly string[] LocaleAbbreviations = new[] {
                "en",
                "es"
                };
            public WordMergeField()
            {
                RawFieldName = String.Empty;
                Name = String.Empty;
                LocaleId = 1;
            }
            public WordMergeField(string rawFieldName)
            : this()
            {
                Parse(rawFieldName);
            }
            public string RawFieldName { get; set; }
            public string Name { get; set; }
            public int LocaleId { get; set; }
            public int BlankLength { get; set; }
            public override bool Equals(object obj)
            {
                var that = obj as WordMergeField;
                if (that == null) return false;
                return Name == that.Name &&
                LocaleId == that.LocaleId &&
                BlankLength == that.BlankLength;
            }
            public override int GetHashCode()
            {
                int hashCode = LocaleId.GetHashCode() ^ BlankLength.GetHashCode();
                if (Name != null) hashCode = hashCode ^ Name.GetHashCode();
                return hashCode;
            }
            public override string ToString()
            {
                //return string.Format("{0} (LocaleId={1}, BlankLength={2})", Name, LocaleId, BlankLength);
                var sb = new StringBuilder();
                if (LocaleId != DefaultLocaleId)
                {
                    sb.AppendFormat("LocaleId={0}", LocaleId);
                }
                if (BlankLength != DefaultBlankLength)
                {
                    if (sb.Length > 0) sb.Append(", ");
                    sb.AppendFormat("BlankLength={0}", BlankLength);
                }
                if (sb.Length > 0)
                {
                    sb.Insert(0, " [");
                    sb.Append("]");
                }
                sb.Insert(0, Name);
                return sb.ToString();
            }
            public void Parse(string rawFieldName)
            {
                RawFieldName = rawFieldName;
                Match match = mRawFieldRegex.Match(rawFieldName);
                if (!match.Success)
                {
                    ParseWithNoMetadata(rawFieldName);
                    return;
                }
                if (match.Groups.Count < 3)
                {
                    throw new Exception("Parse exception - not enough groups matched!");
                }
                Name = match.Groups[1].ToString().Trim();
                // VSTS 9816 - include support for other metadata inside brackets
                string metadata = match.Groups[2].ToString().Trim();
                if (metadata.Length == 0)
                {
                    return;
                }
                foreach (var split in metadata.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string[] pair = split.Trim().Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    if (pair.Length == 1)
                    {
                        // No '=' sign; assume this is a locale
                        ParseLocale(pair[0]);
                    }
                    else
                    {
                        var key = pair[0].Trim();
                        var value = pair[1].Trim();
                        if ("locale".Equals(key, StringComparison.OrdinalIgnoreCase))
                        {
                            ParseLocale(value);
                        }
                        else if ("blanklength".Equals(key, StringComparison.OrdinalIgnoreCase) ||
                        "bl".Equals(key, StringComparison.OrdinalIgnoreCase))
                        {
                            BlankLength = Convert.ToInt32(value);
                        }
                        else
                        {
                            // _log.WarnFormat("Unrecognized metadata key: '{0}'", key);
                        }
                    }
                }
            }
            private void ParseLocale(string value)
            {
                int localeId;
                if (TryParseLocale(value, out localeId))
                {
                    LocaleId = localeId;
                }
                else
                {
                    // _log.WarnFormat("Unrecognized locale value '{0}", value);
                }
            }
            /// 

            /// Returns true if the merge field matches the text in the parent document
            /// 

            /// 
            public bool Matches(string parentText)
            {
                //_log.DebugFormat("Matches: mFieldName = '{0}', parentText = '{1}'", mFieldName, parentText);
                Match match = mParentTextRegex.Match(parentText);
                if (!match.Success || match.Groups.Count < 2)
                {
                    return false;
                }
                string parentFieldName = match.Groups[1].ToString().Trim();
                bool result = RawFieldName.Equals(parentFieldName, StringComparison.InvariantCultureIgnoreCase);
                //_log.Debug("Returning " + result);
                return result;
            }
            private void ParseWithNoMetadata(string rawFieldName)
            {
                Name = rawFieldName.Trim();
            }
            private static bool TryParseLocale(string localePart, out int localeId)
            {
                int localeIndex = Array.IndexOf(FullLocaleNames, localePart.ToLower());
                if (localeIndex >= 0)
                {
                    localeId = localeIndex + 1;
                    return true;
                }
                localeIndex = Array.IndexOf(LocaleAbbreviations, localePart.ToLower());
                if (localeIndex >= 0)
                {
                    localeId = localeIndex + 1;
                    return true;
                }
                localeId = -1;
                return false;
            }
        }
    }
}

v

Hi,

Thanks for the additional information. Using the latest version of Aspose.Words (14.2.0) and your code, I produced a PDF file on my side and attached it here for your reference. I am afraid, I could not see any issue with this output document, could you please clarify where the issue is?

Best regards,

Hello,
Thank you for getting back to me. As you will see in the document you attached, content below the title on the first page “Main Header File” and “Rich TextMerge|DM” is pushed down to the second page. There is a break (an entire page) between these titles and where the “Achilles tenditis” section starts. The Achilles tenditis content should be on the first page immediately following the titles/headers.
It is very important that I am able to get this content created properly. We do not see this gap in content in previous versions of the Aspose.Words library we use. It is extremely important that we use the new Aspose library we purchased, we cannot go rollback to an old Aspose library since the new assembly helps with other content issues. We have customers that are waiting for updated documents and this is an extremely important issue for my company.
Best regards.

Hi,

Thanks for the additional information. I tested the scenario and have managed to reproduce the same problem on my side. For the sake of correction, I have logged this problem in our issue tracking system as WORDSNET-9914. Our development team will further look into the details of this problem and we will keep you updated on the status of correction. We apologize for your inconvenience.

Could you please also provide a little more information about the Aspose.Words’ version number for which there were no problems on your side previously?

Best regards,

Hello,
Thank you for your response. The Aspose version for which there were no problems on our side previously is: 9.3.0.0 . Please let me know if you require any further information.
Thank you again.

Hello,
I have another question. Do you happen to have a general idea for a timeframe for a potential fix? The reason I ask is because we are trying to determine if we need to roll back to the previous version or if the fix will be generated quickly by your development team.
Do you think the fix can be generated with a day or two, a week, a couple weeks, month etc…?
Thank you.

Hi,

Thanks for the additional information. Your issue is pending for analysis and is in the queue. Unfortunately, at the moment we cannot provide you any reliable estimate for this issue. Once the analysis of this issue is completed, we will then be able to provide you more information on the ETA. Sorry for the inconvenience.

Best regards,

Hello,
Thank you for getting back to me. Are there any suggested code work-arounds to eliminate that blank section between pages one and two inside of the Aspose document? Any expedited solution to circumvent the problem will be really helpful.
Thank you again for your help.

Hi,

Thanks for your request. Please spare us some time; our development team will investigate the root cause of this issue. Once your issue is analyzed, we will then provide you information on the root cause and workaround (if possible). We apologize for any inconvenience.

Best regards,

Hello,
I am just checking in to see if any progress has been made on this issue with your development staff and if so is there is an estimated release date for an update?
Thank you.

Hi,

Thanks for your inquiry. Yes, our development team has completed the analysis of this issue and the root cause has been determined. We have asked the ETA of this issue from our development team and will update you as soon as it is available. We apologize for the delay.

Best regards,

Thank you for your quick response. I will await your notification of an ETA from the development department. Thank you again for your help.
Regards - Dave

Hi Dave,

Thanks for being patient. I will update you as soon as I have the required information.

Best regards,

Hi Dave,

Thanks for being patient. Unfortunately, at the moment we cannot provide you any reliable estimate and it is not likely to be fixed in the near future. The implementation of the fix to this issue is postponed till a later date and we cannot push it into production right now because there are many other important issues we have to work on. We will inform you via this thread as soon as this issue is resolved. We apologize for your inconvenience.

Best regards,

Hello,
Thank you for getting back to me. Is it possible for you to provide me with a name or contact information so that we may speak with someone to express our concern about this problem. Our application is dependent upon your software functioning as designed and this limits our ability to provide future fully operational systems to our clients. Can we speak with a member of the development or managerial staff to further address this issue?
Thank you.

Hi Dave,

Thanks for your request. We understand that this issue is important to you and it is unfortunate that this issue has been postponed. We apologize for the inconvenience.

Normally when an issue is reported by a customer, it is added to the pool of current issues being worked on by our developers. Our developers work on issues on a first come, first served basis. We feel this is the fairest and most appropriate way to satisfy the needs of the majority of our customers. We also try to resolve important issue in a timely manner. However, due to the nature of some bugs and the number of features we are working on, this doesn’t always mean we can fix every bug within a short time after it’s reported.

That being said, we fully understand that you are keen to get a fix to your particular issue, please have a look at enhanced support options - e.g. purchasing Priority Support will allow you to post your issues in our Priority Support forum and raise the priority of these issues directly with our development teams, if possible, we will then aim to get a resolution to your issue as soon as we can. Many Priority Support customers find that this leads to their issue being fixed in the next release of the software.

If you would like to take advantage of Enhanced Support then please request a quote in our purchase forum - https://forum.aspose.com/c/purchase/6

Best regards,