ITextSharp 批量电子签章
网上查了很多资料,都没找到可以批量签章的控件,只能自己翻资料PDF签名格式解析、ITextSharp源码,总算是解决了。
其实实现只需要改几行ITextSharp源码,
iTextSharp.text.pdf.PdfSignatureAppearance
添加属性
/// <summary>
/// 多页签章
/// </summary>
private List<int> pageList = new List<int> { 1, 2 };
修改PreClose方法
virtual public void PreClose(Dictionary<PdfName, int> exclusionSizes)
{
if (preClosed)
throw new DocumentException(MessageLocalization.GetComposedMessage("document.already.pre.closed"));
stamper.MergeVerification();
preClosed = true;
AcroFields af = writer.GetAcroFields();
String name = FieldName;
bool fieldExists = af.DoesSignatureFieldExist(name);
PdfIndirectReference refSig = writer.PdfIndirectReference;
writer.SigFlags = 3;
PdfDictionary fieldLock = null;
if (fieldExists)
{
PdfDictionary widget = af.GetFieldItem(name).GetWidget(0);
writer.MarkUsed(widget);
fieldLock = widget.GetAsDict(PdfName.LOCK);
if (fieldLock == null && FieldLockDict != null)
{
widget.Put(PdfName.LOCK, writer.AddToBody(FieldLockDict).IndirectReference);
fieldLock = FieldLockDict;
}
widget.Put(PdfName.P, writer.GetPageReference(Page));
widget.Put(PdfName.V, refSig);
PdfObject obj = PdfReader.GetPdfObjectRelease(widget.Get(PdfName.F));
int flags = 0;
if (obj != null && obj.IsNumber())
flags = ((PdfNumber)obj).IntValue;
flags |= PdfAnnotation.FLAGS_LOCKED;
widget.Put(PdfName.F, new PdfNumber(flags));
PdfDictionary ap = new PdfDictionary();
ap.Put(PdfName.N, GetAppearance().IndirectReference);
widget.Put(PdfName.AP, ap);
}
else
{
PdfFormField sigField = PdfFormField.CreateSignature(writer);
sigField.FieldName = name;
sigField.Put(PdfName.V, refSig);
sigField.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_LOCKED;
if (FieldLockDict != null)
{
sigField.Put(PdfName.LOCK, writer.AddToBody(FieldLockDict).IndirectReference);
fieldLock = FieldLockDict;
}
int pagen = Page;
if (!IsInvisible())
sigField.SetWidget(PageRect, null);
else
sigField.SetWidget(new Rectangle(0, 0), null);
sigField.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, GetAppearance());
foreach (var item in pageList)
{
sigField.Page = item;
writer.AddAnnotation(sigField, item);
}
}
exclusionLocations = new Dictionary<PdfName, PdfLiteral>();
if (cryptoDictionary == null)
{
throw new DocumentException("No crypto dictionary defined.");
}
else
{
PdfLiteral lit = new PdfLiteral(80);
exclusionLocations[PdfName.BYTERANGE] = lit;
cryptoDictionary.Put(PdfName.BYTERANGE, lit);
foreach (KeyValuePair<PdfName, int> entry in exclusionSizes)
{
PdfName key = entry.Key;
int v = entry.Value;
lit = new PdfLiteral(v);
exclusionLocations[key] = lit;
cryptoDictionary.Put(key, lit);
}
if (certificationLevel > 0)
AddDocMDP(cryptoDictionary);
if (fieldLock != null)
AddFieldMDP(cryptoDictionary, fieldLock);
if (signatureEvent != null)
signatureEvent.GetSignatureDictionary(cryptoDictionary);
writer.AddToBody(cryptoDictionary, refSig, false);
}
if (certificationLevel > 0)
{
// add DocMDP entry to root
PdfDictionary docmdp = new PdfDictionary();
docmdp.Put(new PdfName("DocMDP"), refSig);
writer.reader.Catalog.Put(new PdfName("Perms"), docmdp);
}
writer.Close(stamper.MoreInfo);
range = new long[exclusionLocations.Count * 2];
long byteRangePosition = exclusionLocations[PdfName.BYTERANGE].Position;
exclusionLocations.Remove(PdfName.BYTERANGE);
int idx = 1;
foreach (PdfLiteral lit in exclusionLocations.Values)
{
long n = lit.Position;
range[idx++] = n;
range[idx++] = lit.PosLength + n;
}
Array.Sort(range, 1, range.Length - 2);
for (int k = 3; k < range.Length - 2; k += 2)
range[k] -= range[k - 1];
if (tempFile == null)
{
bout = sigout.Buffer;
boutLen = sigout.Size;
range[range.Length - 1] = boutLen - range[range.Length - 2];
ByteBuffer bf = new ByteBuffer();
bf.Append('[');
for (int k = 0; k < range.Length; ++k)
bf.Append(range[k]).Append(' ');
bf.Append(']');
Array.Copy(bf.Buffer, 0, bout, byteRangePosition, bf.Size);
}
else
{
try
{
raf = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite);
long len = raf.Length;
range[range.Length - 1] = len - range[range.Length - 2];
ByteBuffer bf = new ByteBuffer();
bf.Append('[');
for (int k = 0; k < range.Length; ++k)
bf.Append(range[k]).Append(' ');
bf.Append(']');
raf.Seek(byteRangePosition, SeekOrigin.Begin);
raf.Write(bf.Buffer, 0, bf.Size);
}
catch (IOException e)
{
try { raf.Close(); } catch { }
try { File.Delete(tempFile); } catch { }
throw e;
}
}
}
改动只有这一块,每页都添加上签名图像
foreach (var item in pageList)
{
sigField.Page = item;
writer.AddAnnotation(sigField, item);
}
pageList可以自己写个Set方法赋上值
代码很简单,但是找到要改哪块代码却挺费劲,以后有时间再写写解决思路…
也算是劳动成功,我要加上句转载请注明原文链接