当我使用 /Tx 填充文本字段时,我使用它工作的 qpdf。但它不适用于检查 checkBox :
我的代码: if (ffh.getFieldType() == "/Btn")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <qpdf/QPDF.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFAcroFormDocumentHelper.hh>
#include <qpdf/QPDFWriter.hh>
#include <qpdf/QUtil.hh>
#include <QFileDialog>
#include <QDebug>
#include "qtfillpdf.h"
#include "ui_qtfillpdf.h"
qtfillpdf::qtfillpdf(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::qtfillpdf)
{
ui->setupUi(this);
}
qtfillpdf::~qtfillpdf()
{
delete ui;
}
int qtfillpdf::qtfillTESTREPORTpdf( char const* infilename , char const* outfilename,char const* value )
{
qDebug() << "qtfillTESTREPORTpdf : 1 " << value;
// 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.
QPDF qpdf;
qDebug() << "qtfillTESTREPORTpdf : 1.1 " << value;
qpdf.processFile(infilename);
std::string nm;
nm= qpdf.getFilename();
qDebug() << "qtfillTESTREPORTpdf : 2 " << nm.c_str() ;
// We will iterate through form fields by starting at the page
// level and looking at each field for each page. We could
// also called 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);
QPDFPageDocumentHelper pdh(qpdf);
std::vector<QPDFPageObjectHelper> pages = pdh.getAllPages();
qDebug() << "qtfillTESTREPORTpdf : 3 " ;
for (std::vector<QPDFPageObjectHelper>::iterator page_iter =
pages.begin();
page_iter != pages.end(); ++page_iter)
{
// Get all widget annotations for each page. Widget
// annotations are the ones that contain the details of
// what's in a form field.
std::vector<QPDFAnnotationObjectHelper> annotations =
afdh.getWidgetAnnotationsForPage(*page_iter);
char const* checkPASS="true";
char const* checkFAIL="false";
for (std::vector<QPDFAnnotationObjectHelper>::iterator annot_iter = annotations.begin();
annot_iter != annotations.end(); ++annot_iter)
{
// For each annotation, find its associated field. If
// it's a text field, set its value. This will
// automatically update the document to indicate that
// appearance streams need to be regenerated. At the
// time of this writing, qpdf doesn't have any helper
// code to assist with appearance stream generation,
// though there's nothing that prevents it from being
// possible.
//qDebug() << "qtfillTESTREPORTpdf : 4 " << annot_iter->getAppearanceState().c_str() ;
QPDFFormFieldObjectHelper ffh =
afdh.getFieldForAnnotation(*annot_iter);
if (ffh.getFieldType() == "/Tx")
{
//qDebug() << "qtfillTESTREPORTpdf : 5 " <<ffh.getChoices().front().c_str();
// Set the value. This will automatically set
// /NeedAppearances to true. If you don't want to
// do that, pass false as the second argument. For
// details see comments in
// QPDFFormFieldObjectHelper.hh.
ffh.setV(value);
qDebug() << "OK6" << value << " ffh.getValueAsString() : " <<ffh.getValueAsString().c_str();
}
else if (ffh.getFieldType() == "/Btn")
{
//qDebug() << "qtfillTESTREPORTpdf : 5 " <<ffh.getChoices().front().c_str();
// Set the value. This will automatically set
// /NeedAppearances to true. If you don't want to
// do that, pass false as the second argument. For
// details see comments in
// QPDFFormFieldObjectHelper.hh.
ffh.setV(checkPASS);
qDebug() << "OK7" << checkPASS << " ffh.getValueAsString() : " << ffh.getValueAsString().c_str() << endl;
qDebug() << "OK7- 2 " << checkPASS << " ffh.getValue().getName() : " <<ffh.getValue().getName().c_str() << endl;
}
}
}
// Write out a new file
QPDFWriter w(qpdf, outfilename);
w.setStaticID(true); // for testing only
w.write();
return 3;
}
void qtfillpdf::on_Browse_clicked()
{
QString s_configFileName;
QString outfilename = "OUTTESTREPORTWithCheckedBoxes.pdf";
QString value="OkeyMenIfillAutomaticallyYourSheet";
s_configFileName = QFileDialog::getOpenFileName(
this,
tr("Selectionner le fichier de configuration [xlsm]"),
"",
tr("pdf Files (*.pdf)")
);
qDebug() << "File Name : " << s_configFileName ;
qtfillTESTREPORTpdf(s_configFileName.toStdString().c_str(), outfilename.toStdString().c_str(), value.toStdString().c_str());
qDebug()<< " END_BROWSE :" << s_configFileName ;
}
谁知道为什么它对 Btn 不起作用,尽管它对 /Tx 有效
/Tx 的日志,我在 outputPDF 上看到它
OK6 OkeyMenIfillAutomaticallyYourSheet ffh.getValueAsString() : OkeyMenIfillAutomaticallyYourSheet
Btn 的日志:outputPDF 上没有任何内容
WARNING: object stream 1979, object 1129 0 at offset 41539 -> dictionary key /V: operation for name attempted on object of type null: returning dummy name
OK7- 2 true ffh.getValue().getName() : /QPDFFakeName
我知道 qpdf 在我的 pdf 中看不到 /Yes 或 /Off 但也没有 /Tx 并且在 qpdf 示例中没有 /Yes 或 /Off 文件名
需要帮助以获得好主意,谢谢
lib源代码的有趣部分:
void
QPDFFormFieldObjectHelper::setV(
QPDFObjectHandle value, bool need_appearances)
{
if (getFieldType() == "/Btn")
{
if (isCheckbox())
{
bool okay = false;
if (value.isName())
{
std::string name = value.getName();
if ((name == "/Yes") || (name == "/Off"))
{
okay = true;
setCheckBoxValue((name == "/Yes"));
}
}
if (! okay)
{
this->oh.warnIfPossible(
"ignoring attempt to set a checkbox field to a"
" value of other than /Yes or /Off");
}
}
else if (isRadioButton())
{
if (value.isName())
{
setRadioButtonValue(value);
}
else
{
this->oh.warnIfPossible(
"ignoring attempt to set a radio button field to"
" an object that is not a name");
}
}
else if (isPushbutton())
{
this->oh.warnIfPossible(
"ignoring attempt set the value of a pushbutton field");
}
return;
}
if (value.isString())
{
setFieldAttribute(
"/V", QPDFObjectHandle::newUnicodeString(value.getUTF8Value()));
}
else
{
setFieldAttribute("/V", value);
}
if (need_appearances)
{
QPDF* qpdf = this->oh.getOwningQPDF();
if (! qpdf)
{
throw std::logic_error(
"QPDFFormFieldObjectHelper::setV called with"
" need_appearances = true on an object that is"
" not associated with an owning QPDF");
}
QPDFAcroFormDocumentHelper(*qpdf).setNeedAppearances(true);
}
}
void
QPDFFormFieldObjectHelper::setV(
std::string const& utf8_value, bool need_appearances)
{
setV(QPDFObjectHandle::newUnicodeString(utf8_value),
need_appearances);
}
qpdf .dll 的源代码:
我在 answare 上添加了一些澄清元素
提前感谢您的帮助!!!!