Insertar y Adjuntar Documentos

A veces es necesario combinar varios documentos en uno solo. Puede hacer esto manualmente o puede usar la función Aspose.Words insertar o agregar.

La operación insertar le permite insertar el contenido de documentos creados previamente en uno nuevo o existente.

A su vez, la función anexar le permite agregar un documento solo al final de otro documento.

En este artículo se explica cómo insertar o anexar un documento a otro de diferentes maneras y se describen las propiedades comunes que puede aplicar al insertar o anexar documentos.

Insertar un Documento

Como se mencionó anteriormente, en Aspose.Words un documento se representa como un árbol de nodos, y la operación de insertar un documento en otro es copiar nodos del primer árbol de documentos al segundo.

Puede insertar documentos en una variedad de ubicaciones de diferentes maneras. Por ejemplo, puede insertar un documento a través de una operación de reemplazo, un campo de combinación durante una operación de combinación o mediante un marcador.

También puede utilizar el método InsertDocument o InsertDocumentInline, que es similar a insertar un documento en Microsoft Word, para insertar un documento completo en la posición actual del cursor sin importar previamente.

El siguiente ejemplo de código muestra cómo insertar un documento utilizando el método InsertDocument:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document srcDoc = new Document(getMyDir() + "Document source.docx");
Document dstDoc = new Document(getMyDir() + "Northwind traders.docx");
DocumentBuilder builder = new DocumentBuilder(dstDoc);
builder.moveToDocumentEnd();
builder.insertBreak(BreakType.PAGE_BREAK);
builder.insertDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
builder.getDocument().save(getArtifactsDir() + "JoinAndAppendDocuments.insertDocument.docx");

El siguiente ejemplo de código muestra cómo insertar un documento utilizando el método InsertDocumentInline:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
DocumentBuilder srcDoc = new DocumentBuilder();
srcDoc.write("[src content]");
// Create destination document.
DocumentBuilder dstDoc = new DocumentBuilder();
dstDoc.write("Before ");
dstDoc.insertNode(new BookmarkStart(dstDoc.getDocument(), "src_place"));
dstDoc.insertNode(new BookmarkEnd(dstDoc.getDocument(), "src_place"));
dstDoc.write(" after");
Assert.assertEquals("Before after", dstDoc.getDocument().getText().trim());
// Insert source document into destination inline.
dstDoc.moveToBookmark("src_place");
dstDoc.insertDocumentInline(srcDoc.getDocument(), ImportFormatMode.USE_DESTINATION_STYLES, new ImportFormatOptions());
Assert.assertEquals("Before [src content] after", dstDoc.getDocument().getText().trim());

Las siguientes subsecciones describen las opciones durante las cuales puede insertar un documento en otro.

Insertar un Documento Durante la Operación de Búsqueda y reemplazo

Puede insertar documentos mientras realiza operaciones de búsqueda y reemplazo. Por ejemplo, un documento puede contener párrafos con el texto [INTRODUCTION] y [CONCLUSION]. Pero en el documento final, debe reemplazar esos párrafos con el contenido obtenido de otro documento externo. Para lograrlo, deberá crear un controlador para el evento replace.

El siguiente ejemplo de código muestra cómo crear un controlador para el evento de reemplazo para usarlo más adelante en el proceso de inserción:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
private static class InsertDocumentAtReplaceHandler implements IReplacingCallback
{
public /*ReplaceAction*/int /*IReplacingCallback.*/replacing(ReplacingArgs args) throws Exception
{
Document subDoc = new Document(getMyDir() + "Document insertion 2.docx");
// Insert a document after the paragraph, containing the match text.
Paragraph para = (Paragraph)args.getMatchNode().getParentNode();
insertDocument(para, subDoc);
// Remove the paragraph with the match text.
para.remove();
return ReplaceAction.SKIP;
}
}

El siguiente ejemplo de código muestra cómo insertar contenido de un documento en otro durante una operación de búsqueda y reemplazo:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx");
// Set find and replace options.
FindReplaceOptions options = new FindReplaceOptions();
{
options.setDirection(FindReplaceDirection.BACKWARD);
options.setReplacingCallback(new InsertDocumentAtReplaceHandler());
}
// Call the replace method.
mainDoc.getRange().replace(Pattern.compile("\\[MY_DOCUMENT\\]"), "", options);
mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtReplace.docx");

Insertar un documento Durante la Operación Mail Merge

Puede insertar un documento en un campo de combinación durante una operación Mail Merge. Por ejemplo, una plantilla Mail Merge puede contener un campo de combinación como [Resumen]. Pero en el documento final, debe insertar contenido obtenido de otro documento externo en este campo de combinación. Para lograrlo, deberá crear un controlador para el evento de fusión.

El siguiente ejemplo de código muestra cómo crear un controlador para el evento de fusión para usarlo más adelante en el proceso de inserción:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
private static class InsertDocumentAtMailMergeHandler implements IFieldMergingCallback
{
// This handler makes special processing for the "Document_1" field.
// The field value contains the path to load the document.
// We load the document and insert it into the current merge field.
public void /*IFieldMergingCallback.*/fieldMerging(FieldMergingArgs args) throws Exception
{
if ("Document_1".equals(args.getDocumentFieldName()))
{
// Use document builder to navigate to the merge field with the specified name.
DocumentBuilder builder = new DocumentBuilder(args.getDocument());
builder.moveToMergeField(args.getDocumentFieldName());
// The name of the document to load and insert is stored in the field value.
Document subDoc = new Document((String)args.getFieldValue());
insertDocument(builder.getCurrentParagraph(), subDoc);
// The paragraph that contained the merge field might be empty now, and you probably want to delete it.
if (!builder.getCurrentParagraph().hasChildNodes())
builder.getCurrentParagraph().remove();
// Indicate to the mail merge engine that we have inserted what we wanted.
args.setText(null);
}
}
public void /*IFieldMergingCallback.*/imageFieldMerging(ImageFieldMergingArgs args)
{
// Do nothing.
}
}

El siguiente ejemplo de código muestra cómo insertar un documento en el campo de combinación utilizando el controlador creado:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx");
mainDoc.getMailMerge().setFieldMergingCallback(new InsertDocumentAtMailMergeHandler());
// The main document has a merge field in it called "Document_1".
// The corresponding data for this field contains a fully qualified path to the document.
// That should be inserted to this field.
mainDoc.getMailMerge().execute(new String[] { "Document_1" }, new Object[] { getMyDir() + "Document insertion 2.docx" });
mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtMailMerge.doc");

Insertar un documento en el Marcador

Puede importar un archivo de texto a un documento e insertarlo justo después de un marcador que haya definido en el documento. Para hacer esto, cree un párrafo marcado donde desee insertar el documento.

El siguiente ejemplo de codificación muestra cómo insertar el contenido de un documento en un marcador de otro documento:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document mainDoc = new Document(getMyDir() + "Document insertion 1.docx");
Document subDoc = new Document(getMyDir() + "Document insertion 2.docx");
Bookmark bookmark = mainDoc.getRange().getBookmarks().get("insertionPlace");
insertDocument(bookmark.getBookmarkStart().getParentNode(), subDoc);
mainDoc.save(getArtifactsDir() + "CloneAndCombineDocuments.InsertDocumentAtBookmark.docx");

Anexar un Documento

Es posible que tenga un caso de uso en el que necesite incluir páginas adicionales de un documento hasta el final de un documento existente. Para hacer esto, solo necesita llamar al método AppendDocument para agregar un documento al final de otro.

El siguiente ejemplo de código muestra cómo anexar un documento al final de otro documento:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document dstDoc = new Document();
dstDoc.getFirstSection().getBody().appendParagraph("Destination document text. ");
Document srcDoc = new Document();
srcDoc.getFirstSection().getBody().appendParagraph("Source document text. ");
// Append the source document to the destination document.
// Pass format mode to retain the original formatting of the source document when importing it.
dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.KeepSourceFormatting.docx");

Importar e insertar nodos manualmente

Aspose.Words le permite insertar y adjuntar documentos automáticamente sin ningún requisito de importación previo. Sin embargo, si necesita insertar o agregar un nodo específico de su documento, como una sección o un párrafo, primero debe importar este nodo manualmente.

Cuando necesite insertar o agregar una sección o párrafo a otra, esencialmente necesita importar los nodos del primer árbol de nodos del documento al segundo utilizando el método ImportNode. Después de importar sus nodos, debe usar el método InsertAfter para insertar un nuevo nodo después/antes del nodo de referencia. Esto le permite personalizar el proceso de inserción importando nodos de un documento e insertándolo en posiciones determinadas.

También puede usar el método AppendChild para agregar un nuevo nodo especificado al final de la lista de nodos secundarios, por ejemplo, si desea agregar contenido a nivel de párrafo en lugar de a nivel de sección.

El siguiente ejemplo de código muestra cómo importar nodos manualmente e insertarlos después de un nodo específico usando el método InsertAfter:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
/// <summary>
/// Inserts content of the external document after the specified node.
/// Section breaks and section formatting of the inserted document are ignored.
/// </summary>
/// <param name="insertionDestination">Node in the destination document after which the content
/// Should be inserted. This node should be a block level node (paragraph or table).</param>
/// <param name="docToInsert">The document to insert.</param>
private static void insertDocument(Node insertionDestination, Document docToInsert)
{
if (insertionDestination.getNodeType() == NodeType.PARAGRAPH || insertionDestination.getNodeType() == NodeType.TABLE)
{
CompositeNode destinationParent = insertionDestination.getParentNode();
NodeImporter importer =
new NodeImporter(docToInsert, insertionDestination.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);
// Loop through all block-level nodes in the section's body,
// then clone and insert every node that is not the last empty paragraph of a section.
for (Section srcSection : docToInsert.getSections())
for (Node srcNode : srcSection.getBody())
{
if (srcNode.getNodeType() == NodeType.PARAGRAPH)
{
Paragraph para = (Paragraph)srcNode;
if (para.isEndOfSection() && !para.hasChildNodes())
continue;
}
Node newNode = importer.importNode(srcNode, true);
destinationParent.insertAfter(newNode, insertionDestination);
insertionDestination = newNode;
}
}
else
{
throw new IllegalArgumentException("The destination node should be either a paragraph or table.");
}
}

El contenido se importa en el documento de destino sección por sección, lo que significa que la configuración, como la configuración de la página y los encabezados o pies de página, se conservan durante la importación. También es útil tener en cuenta que puede definir la configuración de formato al insertar o anexar un documento para especificar cómo se unen dos documentos.

Propiedades comunes para Insertar y Anexar documentos

Ambos métodos InsertDocument y AppendDocument aceptan ImportFormatMode y ImportFormatOptions como parámetros de entrada. ImportFormatMode le permite controlar cómo se fusiona el formato del documento cuando importa contenido de un documento a otro seleccionando diferentes modos de formato, como UseDestinationStyles, KeepSourceFormatting y KeepDifferentStyles. ImportFormatOptions le permite seleccionar diferentes opciones de importación, como IgnoreHeaderFooter, IgnoreTextBoxes, KeepSourceNumbering, MergePastedLists, y SmartStyleBehavior.

Aspose.Words le permite ajustar la visualización de un documento resultante cuando se agregan dos documentos en una operación de inserción o anexión mediante las propiedades Section y PageSetup. La propiedad PageSetup contiene todos los atributos de una sección, como SectionStart, RestartPageNumbering, PageStartingNumber, Orientation, y otros. El caso de uso más común es establecer la propiedad SectionStart para definir si el contenido agregado aparecerá en la misma página o se dividirá en una nueva.

El siguiente ejemplo de código muestra cómo anexar un documento a otro evitando que el contenido se divida en dos páginas:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document srcDoc = new Document(getMyDir() + "Document source.docx");
Document dstDoc = new Document(getMyDir() + "Northwind traders.docx");
// Set the source document to continue straight after the end of the destination document.
srcDoc.getFirstSection().getPageSetup().setSectionStart(SectionStart.CONTINUOUS);
// Restart the page numbering on the start of the source document.
srcDoc.getFirstSection().getPageSetup().setRestartPageNumbering(true);
srcDoc.getFirstSection().getPageSetup().setPageStartingNumber(1);
// To ensure this does not happen when the source document has different page setup settings, make sure the
// settings are identical between the last section of the destination document.
// If there are further continuous sections that follow on in the source document,
// this will need to be repeated for those sections.
srcDoc.getFirstSection().getPageSetup().setPageWidth(dstDoc.getLastSection().getPageSetup().getPageWidth());
srcDoc.getFirstSection().getPageSetup().setPageHeight(dstDoc.getLastSection().getPageSetup().getPageHeight());
srcDoc.getFirstSection().getPageSetup().setOrientation(dstDoc.getLastSection().getPageSetup().getOrientation());
// Iterate through all sections in the source document.
for (Paragraph para : (Iterable<Paragraph>) srcDoc.getChildNodes(NodeType.PARAGRAPH, true))
{
para.getParagraphFormat().setKeepWithNext(true);
}
dstDoc.appendDocument(srcDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
dstDoc.save(getArtifactsDir() + "JoinAndAppendDocuments.DifferentPageSetup.docx");