Смысл в следующем - создается страница и к ней прикрепляется аннотация размером 0 на 0. Таких аннотаций на страницу может быть много. В качестве аннотации может быть текст, картинка или вложенный файл. Вот этим и воспользуемся.
Итак - сама страница будет отображать данные в красивом виде, таблички там и прочее. Это нам неинтересно на данном этапе. Сейчас важно научиться создавать вложенные файлы.
Вот пример кода, который поместит все файлы из некого каталога в аннотацию к первой странице PDF.
{
PdfMemDocument document;
//создаем страницу
PdfPage* pPage = document.CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) );
//визуальное отображение страницы
PdfPainter painter;
painter.SetPage( pPage );
PdfFont * pFont = document.CreateFont( "Arial" );
pFont->SetFontSize( 18.0 );
painter.SetFont( pFont );
painter.DrawText( 56.69, pPage->GetPageSize().GetHeight() - 56.69, "PDF PAGE");
painter.FinishPage();
QDir dr("E:\\DIR");
dr.setFilter(QDir::Files);
QStringList lst = dr.entryList();
foreach (QString file, lst)
{
QString filename = dr.absolutePath() + "/" + file;
PdfAnnotation * pAnn = pPage->CreateAnnotation(ePdfAnnotation_FileAttachement,
PdfRect());
PdfFileSpec filespec(filename.toStdString().c_str(), true, &document);
pAnn->SetFileAttachement(filespec);
}
document.Write("test.pdf");
}
* This source code was highlighted with Source Code Highlighter.
Более сложным было понять как извлечь аттачи. Документаци на этот счет крайне скудна, пришлось разбираться по исходному коду и изучать спецификацию по PDF от Adobe.Вот код, который извлекает все аттачи и складывает их в папку.
{
PdfMemDocument doc("test.pdf");
PdfVecObjects vec = doc.GetObjects();
PdfPage* page = doc.GetPage(0);
int numann = page->GetNumAnnots();
QString dirname = "e:/OUT/";
for (int i = 0; i < numann; i++)
{
PdfAnnotation * pAnn = page->GetAnnotation(i);
if (pAnn->HasFileAttachement())
{
PdfFileSpec * attach = pAnn->GetFileAttachement();
QString filename(attach->GetFilename().GetString());
int li = filename.lastIndexOf("/");
filename = filename.mid(li + 1);
PdfObject * obj = attach->GetObject();
PdfDictionary pob = obj->GetDictionary().GetKey( "EF")->GetDictionary();
PdfReference ref = pob.GetKey("F")->GetReference();
PdfObject * obstream = vec.GetObject(ref);
if (obstream->HasStream())
{
PdfStream * stream = obstream->GetStream();
char* pDecoded;
pdf_long lDecoded;
stream->GetFilteredCopy(&pDecoded, &lDecoded);
PdfFileOutputStream out(QString(dirname + filename).toStdString().c_str());
out.Write(pDecoded, lDecoded);
out.Close();
}
}
}
}
* This source code was highlighted with Source Code Highlighter.
Отличная статья!
ОтветитьУдалитьА как средствами PoDoFo сделать в Qt простой viewer pdf-файлов?