Using AppendDocument or similar functionality in Classic ASP

I am trying to use Aspose.Words for .NET through COM Interop in a classic ASP web app to merge one or more word documents into a single document. I had hoped to be able to do this without creating a wrapper class. I’ve spent a fair amount of time searching the forums and the API documentation but I don’t seem to be able to get this right.

In my ASP application, I am attempting the following:

dim MergeTarget, MergeTargetSavePath, MergeHelper
set MergeTarget = CreateObject("Aspose.Words.Document")
set MergeHelper = CreateObject("Aspose.Words.ComHelper")
MergeTarget.RemoveAllChildren()
do until rsSQL.EOF
if fso.FileExists(rsSQL(0)) then
MergeHelper.Open(rsSQL(0))

'MergeTarget.AppendDocument MergeHelper,1
response.Write("File to append is " & rsSQL(0) & "")
else
'need to keep track of missing files somehow
response.Write("Source document " & rsSQL(0) & " was not found.")
end if

rsSQL.MoveNext
loop
rsSQL.Close
MergeTargetSavePath = UploadLoc & "" & arMergeList(4,i)
response.Write("MergeTargetSavePath is " & MergeTargetSavePath & "")
MergeTarget.Save(MergeTargetSavePath)
set MergeTarget = nothing

I can successfully create both the Document and ComHelper objects, and I’m sure I could create a DocumentBuilder object. I can remove the children from the Document, I can load from the file system into the ComHelper, and I can save the Document. What I can’t figure out how to do is correctly utilize the AppendDocument with the KeepSourceFormatting enum. I looked up the enum value and tried using it explicitly (1) and I’ve tried different combinations of the Document and ComHelper object but I can’t seem to get it right.

As I mentioned, I’d prefer to do this without creating a wrapper class but if that is not possible, I’d appreciate some guidance on creating a simple wrapper class that would allow me to do what I’ve described. I’ve seen several sample wrapper classes in the forums but I didn’t find one that exposed AppendDocument.

Thanks for your help,
Nathaniel

Hi Nathaniel,

Thanks for your inquiry. Please use the following code snippet to merge documents.

'Create comhelper
Dim comHelper
Set comHelper = CreateObject("Aspose.Words.ComHelper")
'open destination and source documents
Dim dstDoc
Set dstDoc = comHelper.Open(Server.MapPath("dst.doc"))
Dim srcDoc
Set srcDoc = comHelper.Open(Server.MapPath("src.doc"))
'Append source document to destination
Dim dstSection
Dim i
For i=0 To srcDoc.Sections.Count - 1
Set dstSection = dstDoc.ImportNode_2(srcDoc.Sections.Item(i), True, 1 )
dstDoc.AppendChild( dstSection )
Next
'Save output document
dstDoc.Save(Server.MapPath("out.doc"))

Hope this helps you. Please let us know if you have any more queries.

Tahir,

Thank you for your reply. I had found that code snippet in another thread and have been trying to implement it but I’m getting an error on the For statement:

Microsoft VBScript runtime error ‘800a01a8’
Object required: ‘Aspose.Words.Documen’
/review/CreateZipCritique.asp, line 161
Line 161 is:
for j = 0 to FileToMerge.Sections.Count - 1

My code is slightly different. I’m not using Server.MapPath because I have the full path to the files which are stored on a NAS coming from a recordset. I’m also checking that the file actually exists in case the database contains an invalid path. The first two file paths returned from the recordset, that I’m response.writing, are:

MergeTarget file is U:\uploadedfiles\Review\Uploads123\16\2280\CTIG_AKAR____5-2010SI297553.DOC
FileToMerge file is U:\uploadedfiles\Review\Uploads123\16\2280\CTIG_AKAR____5-2010RI300764.DOC

dim MergeTarget, MergeTargetSavePath, MergeHelper, MergeBuilder, FileToMerge, MergeSection, j
' MergeTarget = CreateObject("Aspose.Words.Document")
set MergeHelper = CreateObject("Aspose.Words.ComHelper")
'set MergeBuilder = CreateObject("Aspose.Words.DocumentBuilder")
'MergeTarget.RemoveAllChildren()
'MergeTarget = MergeHelper.Open()

'First loop gets first file in recordset that exists and loads into MergeTarget/destination document
do until rsSQL.EOF
response.Write("MergeTarget file is " & rsSQL(0) & "")
if fso.FileExists(rsSQL(0)) then

MergeTarget = MergeHelper.Open(rsSQL(0))
rsSQL.MoveNext
exit do
else
'Missing file
response.Write("Source document " & rsSQL(0) & " was not found.")
rsSQL.MoveNext
end if
loop

do until rsSQL.EOF
response.Write("FileToMerge file is " & rsSQL(0) & "")
if fso.FileExists(rsSQL(0)) then
FileToMerge = MergeHelper.Open(rsSQL(0))
for j = 0 to FileToMerge.Sections.Count - 1
Set MergeSection = MergeTarget.ImportNode_2(FileToMerge.Sections.Item(j), True, 1 )
MergeTarget.AppendChild(MergeSection)
next
else
'need to keep track of missing files somehow
response.Write("Source document " & rsSQL(0) & " was not found.")
end if

rsSQL.MoveNext
loop

rsSQL.Close
MergeTargetSavePath = UploadLoc & "\" & arMergeList(4,i)
response.Write("MergeTargetSavePath is " & MergeTargetSavePath & "")
MergeTarget.Save(MergeTargetSavePath)
set MergeTarget = nothing

Hi Nathaniel,

Thanks for your inquiry. Please use the Set keyword to create object as shown below. Hope this helps you. Please let us know if you have any more queries.

'open destination and source documents
Dim dstDoc
Set dstDoc = comHelper.Open(Server.MapPath("dst.doc"))
Dim srcDoc
Set srcDoc = comHelper.Open(Server.MapPath("src.doc"))

Tahir,

Thanks very much; I totally overlooked the SET statement in the original code. I’ve got my documents merging successfully and I now have two separate questions. Some of the documents have extraneous carriage returns/paragraphs that cause Word to show an extra page. I’ve read several threads about removing extra pages and I found this block of code in another thread where you had replied to someone looking to accomplish a similar task. I wondered if it is possible to do something similar using the COM Helper or if it would require a wrapper class.

// Open template.
Document doc = new Document(@"Test001\in.doc");
// Remove the empty paragraphs if necessary.
while (!doc.LastSection.Body.LastParagraph.HasChildNodes)
{
    if (doc.LastSection.Body.LastParagraph.PreviousSibling != null &&
    doc.LastSection.Body.LastParagraph.PreviousSibling.NodeType != NodeType.Paragraph)
        break;
    doc.LastSection.Body.LastParagraph.Remove();
    // If the current section becomes empty, we should remove it.
    if (!doc.LastSection.Body.HasChildNodes)
        doc.LastSection.Remove();
    // We should exit the loop if the document becomes empty.
    if (!doc.HasChildNodes)
        break;
}
// Save output.
doc.Save(@"Test001\out.doc");

Also, I wondered if there is an easy way to deal with page numbering in footers. Our documents are based on a template downloaded by users, completed, and then merged in batches. The original template contains a footer with automatic page numbering. When the documents are merged, this causes the numbering to run consecutively through the entire final document. Is there a way to make it restart at 1 for each merged document, again either using the COM Helper or if it would require a wrapper class.

Thanks very much for all your assistance with these questions.

Hi Nathaniel,
Thanks for your inquiry. Please accept my apologies for late response.
Regarding your first query, you need to create wrapper class to achieve your requirements. Please read more about creating the wrapper classes from following link.
How to create a wrapper to assist in calling Aspose.Words methods from classic ASP.
Regarding your second query, to restart the page numbering at the start of section the PageSetup.RestartPageNumbering property must be set to true. The number which this is restarted to is defined by the PageSetup.PageStartingNumber property. This property is set to “1” in Microsoft Word and Aspose.Words by default. For more details, I would suggest you please read the following article:
https://docs.aspose.com/words/net/working-with-fields/
Please check the ASP code snippet for the usage of PageStartingNumber property from following forum link:
Hope this answers your query. Please let us know if you have any more queries.