#include #include #include #include #include #include #include static char const* whoami = nullptr; void usage() { std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf value" << std::endl << "Set the value of all text fields to a specified value" << std::endl; exit(2); } int main(int argc, char* argv[]) { whoami = QUtil::getWhoami(argv[0]); if (argc != 4) { usage(); } char const* infilename = argv[1]; char const* outfilename = argv[2]; char const* value = argv[3]; // This is a contrived example that just goes through a file page by page and sets the value of // any text fields it finds to a fixed value as given on the command line. The purpose here is // to illustrate use of the helper classes around interactive forms. try { QPDF qpdf; qpdf.processFile(infilename); // We will iterate through form fields by starting at the page level and looking at each // field for each page. We could also call QPDFAcroFormDocumentHelper::getFormFields to // iterate at the field level, but doing it as below illustrates how we can map from // annotations to fields. QPDFAcroFormDocumentHelper afdh(qpdf); for (auto const& page: QPDFPageDocumentHelper(qpdf).getAllPages()) { // Get all widget annotations for each page. Widget annotations are the ones that // contain the details of what's in a form field. for (auto& annot: afdh.getWidgetAnnotationsForPage(page)) { // For each annotation, find its associated field. If it's a text field, set its // value. QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(annot); if (ffh.getFieldType() == "/Tx") { // Set the value. Passing false as the second parameter prevents qpdf from // setting /NeedAppearances to true (but will not turn it off if it's already // on), so we call generateAppearance after setting the value. You may or may // not want to do this depending on whether the appearance streams generated by // qpdf are good enough for your purposes. For additional details, please see // comments in QPDFFormFieldObjectHelper.hh for this method. ffh.setV(value, false); ffh.generateAppearance(annot); } } } // Write out a new file QPDFWriter w(qpdf, outfilename); w.setStaticID(true); // for testing only w.write(); } catch (std::exception& e) { std::cerr << whoami << " processing file " << infilename << ": " << e.what() << std::endl; exit(2); } return 0; }