Cómo cargar un documento en C++

Cómo cargar un documento en C++

Aspose.PDF FOSS para C++ abre un PDF existente a través de la clase Document — desde una ruta de archivo simple, o con una contraseña cuando la fuente está cifrada — y expone los metadatos /Info del archivo a través de DocumentInfo. Esta guía cubre la carga de un documento, la detección y apertura de archivos protegidos por contraseña, la lectura y actualización de los metadatos de título/autor/productor, y el guardado del resultado. La biblioteca se agrega a un proyecto mediante CMake; no hay un paso de instalación mediante gestor de paquetes.

Guía paso a paso

Paso 1: Instalar el paquete

Agregue la biblioteca como un subdirectorio de CMake y vincúlela contra el objetivo aspose_pdf_foss:

add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)

Verifique que la cadena de herramientas y los encabezados se resuelvan compilando un programa mínimo:

#include <aspose/pdf/document.hpp>
#include <iostream>

int main() {
    Aspose::Pdf::Document doc;
    std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}

Una compilación exitosa que imprima pages: 0 confirma que la biblioteca está vinculada correctamente.


Paso 2: Importar clases requeridas

#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>

using namespace Aspose::Pdf;

Document y DocumentInfo están declarados directamente bajo el espacio de nombres Aspose::Pdf.


Paso 3: Abrir un documento PDF desde una ruta de archivo

El constructor Document(filename) lee el archivo, analiza su tabla de referencias cruzadas y el árbol de páginas, y construye el modelo en memoria. Lanza std::system_error cuando el archivo no existe o no se puede leer, y std::runtime_error cuando el archivo no es un PDF válido:

#include <iostream>
#include <stdexcept>

try {
    Document doc("input.pdf");
    std::cout << "Pages: " << doc.Pages().Count() << "\n";
} catch (const std::runtime_error& e) {
    std::cerr << "Not a valid PDF: " << e.what() << "\n";
} catch (const std::system_error& e) {
    std::cerr << "Could not read file: " << e.what() << "\n";
}

Paso 4: Abrir un documento protegido con contraseña

El constructor de un solo argumento del Paso 3 nunca autentica una contraseña ni inspecciona la entrada /Encrypt del tráiler, por lo que IsEncrypted() en un documento abierto de esa manera siempre informa false — incluso cuando el archivo fuente realmente está cifrado. Para detectar y abrir un PDF cifrado, utilice el constructor de dos argumentos, que lee /Encrypt y autentica la contraseña que proporcione:

try {
    Document doc("input.pdf", "user-password");
    if (doc.IsEncrypted()) {
        std::cout << "Opened an encrypted document.\n";
    }
} catch (const std::runtime_error& e) {
    // Thrown when /Encrypt is present and the password matches
    // neither the user nor the owner entry in the trailer.
    std::cerr << "Wrong password or unreadable /Encrypt dictionary: "
              << e.what() << "\n";
}

Si el PDF fuente no está cifrado, el argumento de contraseña simplemente se ignora y el documento se abre normalmente — por lo que es seguro usar el constructor de dos argumentos incluso cuando no esté seguro de que un archivo esté protegido.


Paso 5: Leer los metadatos del documento con DocumentInfo

Document.Info() devuelve un DocumentInfo& vinculado al diccionario /Info del documento. Cada campo predefinido tiene su propio accesor de lectura, que devuelve una cadena vacía cuando la clave está ausente del archivo fuente:

Document doc("input.pdf");
DocumentInfo& info = doc.Info();

std::cout << "Title: "    << info.Title()    << "\n";
std::cout << "Author: "   << info.Author()   << "\n";
std::cout << "Subject: "  << info.Subject()  << "\n";
std::cout << "Producer: " << info.Producer() << "\n";
std::cout << "Creator: "  << info.Creator()  << "\n";
std::cout << "Keywords: " << info.Keywords() << "\n";

DocumentInfo::IsPredefinedKey indica si un nombre de clave /Info dado es uno de estos campos incorporados, a diferencia de una clave personalizada añadida con Add:

bool builtin = DocumentInfo::IsPredefinedKey("Title");   // true
bool custom  = DocumentInfo::IsPredefinedKey("MyKey");   // false

Paso 6: Actualizar metadatos y guardar el documento

Establezca los metadatos mediante las sobrecargas del setter correspondientes, o a través del método de conveniencia SetTitle en Document, y luego persista el cambio con Save:

Document doc("input.pdf");
doc.Info().Author("Report Generator");
doc.SetTitle("Quarterly Report");   // equivalent to doc.Info().Title(title)

doc.Save("output.pdf");

Las ediciones de metadatos se preparan en memoria y solo se escriben en la siguiente llamada a Save. Llame a Save(outputFileName) para escribir en una ruta nueva, o al Save() sin argumentos para sobrescribir el archivo desde el que se abrió originalmente el documento:

Document doc("input.pdf");
doc.SetTitle("Updated In Place");
doc.Save();   // writes back to "input.pdf"

Problemas comunes y soluciones

IsEncrypted() returns false para un PDF que sé que está protegido con contraseña

El constructor de un solo argumento Document(path) nunca autentica contra el diccionario /Encrypt del archivo, por lo que IsEncrypted() siempre informa false en un documento abierto de esta manera, independientemente de si la fuente está realmente encriptada. Abra el archivo con el constructor de dos argumentos Document(path, password) en su lugar — es la única sobrecarga que rellena el estado de cifrado.

El constructor de dos argumentos lanza std::runtime_error

Esto significa que el PDF de origen tiene una entrada /Encrypt en su tráiler y la contraseña suministrada no coincide ni con la contraseña de usuario ni con la de propietario registrada allí. Capture std::runtime_error y solicite la contraseña correcta, o confirme la contraseña por otro medio antes de reintentar.

Save() lanza “no source filename to save to”

El Save() sin argumentos escribe de vuelta a la ruta desde la que se construyó el documento. Un Document creado con el constructor sin argumentos — un documento nuevo en memoria sin archivo fuente — no tiene ruta a la que escribir de vuelta, por lo que Save() lanza. Llame a Save(outputFileName) en su lugar.

Decrypt() no parece producir un archivo sin protección

Decrypt() borra la bandera IsEncrypted() en memoria para que las lecturas posteriores traten el documento como texto plano, pero en la versión actual no reescribe el diccionario /Encrypt del tráiler ni vuelve a codificar las cadenas y flujos encriptados. Una llamada a Save() después de Decrypt() aún escribe los bytes originales, incluida la encriptación original — este método aún no produce una copia en texto plano en el disco.

Título/Autor/etc. se imprimen como cadenas vacías

Los accesores de DocumentInfo devuelven una cadena vacía, no un error, cuando la clave /Info correspondiente está ausente del PDF de origen. Un resultado vacío significa que el campo nunca se estableció en ese documento, no que la lectura falló.

Preguntas frecuentes

¿Funciona Document(path) en un PDF cifrado?

Normalmente analiza el árbol de páginas sin lanzar excepciones, pero nunca autentica una contraseña y siempre deja IsEncrypted() en false. Use el constructor de dos argumentos siempre que la fuente pueda estar cifrada.

¿Es seguro pasar una contraseña a Document(path, password) para un archivo que resulta no estar cifrado?

Sí. Cuando el trailer no tiene una entrada /Encrypt, el argumento de contraseña se ignora y el documento se abre de la misma manera que con el constructor de un solo argumento.

¿Cómo distinguir una clave /Info personalizada de una incorporada?

Llame al estático DocumentInfo::IsPredefinedKey(key). Devuelve true para Title, Author, Subject, Keywords, Creator, Producer y Trapped, y false para cualquier otro.

¿Puedo sobrescribir el archivo que acabo de cargar en lugar de escribir en una nueva ruta?

Sí — llame al Save() sin argumentos sobre un Document que se construyó a partir de una ruta de archivo; escribe de nuevo en esa misma ruta de origen. Lanza una excepción para los documentos creados con el constructor sin argumentos, que no tienen ruta de origen.

¿Guardar después de Decrypt() elimina la protección con contraseña del PDF?

No, no en la versión actual — vea los Problemas Comunes arriba. Decrypt() solo afecta al estado en memoria usado por los lectores de contenido; el archivo escrito por Save() sigue conservando el diccionario original /Encrypt.

Ver también

 Español