C# 如何在可填充PDF表单中刷新非计算字段和计算字段的格式

C# 如何在可填充PDF表单中刷新非计算字段和计算字段的格式,c#,vb.net,itextsharp,C#,Vb.net,Itextsharp,我有一个PDF模板文件,我正试图填充“MyDocument”的内容。所有字段都可以填充,但问题是我的PDF中的“计算”字段没有刷新,其他字段的格式也没有设置。如何使用ITextSharp刷新计算字段并设置其格式?(我不在乎是否得到C#或VB.NET答案) VB.NET: Public Shared Sub Serialize(ByVal stmt As MyDocument, ByVal file As FileInfo) Dim reader As

我有一个PDF模板文件,我正试图填充“MyDocument”的内容。所有字段都可以填充,但问题是我的PDF中的“计算”字段没有刷新,其他字段的格式也没有设置。如何使用ITextSharp刷新计算字段并设置其格式?(我不在乎是否得到C#或VB.NET答案)

VB.NET:

  Public Shared Sub Serialize(ByVal stmt As MyDocument, ByVal file As FileInfo)
                    Dim reader As New PdfReader(TemplateFilePath.FullName)
                    Dim pdfStamper As New PdfStamper(reader, New FileStream(file.FullName, FileMode.Open))
                    Try
                        With itsDaDetailFields
                            .MoveFirst()
                            While Not .EOF
                                Dim pdfFieldName As String = NsT(Of String)(!PDFFieldName, Nothing)
                                If Not String.IsNullOrEmpty(pdfFieldName) Then
                                    Dim value As String = NsT(Of String)(stmt.GetValueFromPDFField(pdfFieldName), Nothing)
                                    If Not String.IsNullOrEmpty(value) Then
                                        pdfStamper.AcroFields.SetField(pdfFieldName, value)
                                    End If
                                End If
                                .MoveNext()
                            End While
                        End With

                    Finally
                        pdfStamper.FormFlattening = False
                        reader.Close()
                        pdfStamper.Close()
                    End Try
                End Sub
C#:

publicstaticvoid序列化(mydocumentstmt,FileInfo文件)
{
PdfReader reader=新的PdfReader(TemplateFilePath.FullName);
PdfStamper PdfStamper=新的PdfStamper(读取器,新文件流(file.FullName,FileMode.Open));
试一试{
var_,其中1=其数据详细字段;
_使用1.MoveFirst();
而(!\u带1.EOF){
字符串PdfieldName=NsT(_带1[“PdfieldName”],null);
如果(!string.IsNullOrEmpty(PdfieldName)){
字符串值=NsT(stmt.getValueFromPdfield(PdfieldName),null);
如果(!string.IsNullOrEmpty(值)){
pdfStamper.AcroFields.SetField(pdfFieldName,value);
}
}
_使用1.MoveNext();
}
}最后{
pdfStamper.formflatting=false;
reader.Close();
pdfStamper.Close();
}
}

因此,根据下面使用iText的帖子(ITextSharp的java版本-该过程与.NET略有不同),我想出了如何在.NET中实现这一点。请随意阅读以下主题,以获得iText中相同问题的完整解释和讨论:

有两种方法可以做到这一点:

(1)提供如下显示值:

pdfStamper.AcroFields.SetField(pdfFieldName, value, <formatted value>)
这对我来说不是最好的,因为我无法从我的PDF文件中以编程的方式找出哪些文本框正在以何种格式格式化它们的内容。有些文本框的格式略有不同(有些有2位小数,有些有0位,有些有很多位小数),因此如果您能够跟踪文本框如何格式化其数据,或者如果它们都做相同的事情,那么这可能会起作用。这也没有解决计算字段的问题,只是似乎解决了格式问题

(2)提供javascript来“脏”值,以便对其进行格式化和计算:

pdfStamper.AcroFields.SetField(pdfFieldName, value, <formatted value>)
由于我只需要格式化数值,所以我的代码变成了如下所示,但这可以扩展到处理其他类型(见下面的讨论)

所以诀窍在于,您需要使用JavaScript将值弄脏,然后读取器将应用格式。您可以在下面提供的完整解决方案的基础上对其进行更多的概括,并处理更多的值类型(很抱歉,它是用java编写的,但可以适应.net):


因此,我根据下面使用iText的帖子(ITextSharp的java版本-该过程与.NET稍有不同),了解了如何在.NET中实现这一点。请随意阅读以下主题,以获得iText中相同问题的完整解释和讨论:

有两种方法可以做到这一点:

(1)提供如下显示值:

pdfStamper.AcroFields.SetField(pdfFieldName, value, <formatted value>)
这对我来说不是最好的,因为我无法从我的PDF文件中以编程的方式找出哪些文本框正在以何种格式格式化它们的内容。有些文本框的格式略有不同(有些有2位小数,有些有0位,有些有很多位小数),因此如果您能够跟踪文本框如何格式化其数据,或者如果它们都做相同的事情,那么这可能会起作用。这也没有解决计算字段的问题,只是似乎解决了格式问题

(2)提供javascript来“脏”值,以便对其进行格式化和计算:

pdfStamper.AcroFields.SetField(pdfFieldName, value, <formatted value>)
由于我只需要格式化数值,所以我的代码变成了如下所示,但这可以扩展到处理其他类型(见下面的讨论)

所以诀窍在于,您需要使用JavaScript将值弄脏,然后读取器将应用格式。您可以在下面提供的完整解决方案的基础上对其进行更多的概括,并处理更多的值类型(很抱歉,它是用java编写的,但可以适应.net):


就我而言,我发现:

  • 使用FormFlating可以防止javascript更新字段
  • 使用SetField设置字段不会触发格式化
  • 因此,我必须更改javascript,以实际编写完整的值,而不是将其弄脏。像这样:

    JS &= String.Format("var f = this.getField('{0}'); f.value = '{1}';",
                        FieldName.Key, NewFieldValue)
    

    我将每个字段的javascript代码附加到字符串JS中,然后在末尾调用
    pdfStamper.javascript=JS

    在我的例子中,我发现:

  • 使用FormFlating可以防止javascript更新字段
  • 使用SetField设置字段不会触发格式化
  • 因此,我必须更改javascript,以实际编写完整的值,而不是将其弄脏。像这样:

    JS &= String.Format("var f = this.getField('{0}'); f.value = '{1}';",
                        FieldName.Key, NewFieldValue)
    

    我将每个字段的javascript代码附加到字符串JS中,然后在末尾调用
    pdfStamper.javascript=JS

    根据此链接中引用的2006年的帖子,这是不受支持的。在过去的7年里可能发生了一些变化,但我猜不会。有什么地方可以找到更多关于这方面的信息吗?我会直接进入iText邮件列表。首先,搜索是否有更新的答案,然后询问是否找不到任何东西。根据该链接中引用的2006年的帖子,这是不受支持的。在过去的7年里可能发生了一些变化,但我猜不会。有什么地方可以找到更多关于这方面的信息吗?我会直接进入iText邮件列表。首先,搜索是否有更新的答案,然后询问是否找不到任何东西。我已经在一个日期字段上应用了这个解决方案,它成功了。我面临的一个问题是,再次单击PDF中的日期字段会更改日期格式。因此,我必须使日期字段为只读,以使其工作。如果
    JS &= String.Format("var f = this.getField('{0}'); f.value = '{1}';",
                        FieldName.Key, NewFieldValue)