iText7을 사용하여 편집 가능한 양식 필드가있는 일부 PDF 문서를 생성 중입니다. 내 코드는 다음 코드를 사용하여 PDF 문서에 필드를 추가합니다PDF AcroForm 필드가 Acrobat에서 먼저 수정 된 다음 iText7에서 공백이됩니다.
@Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
PdfAcroForm form = PdfAcroForm.getAcroForm(drawContext.getDocument(), true);
PdfFormField field = isMultiline
? PdfFormField.createMultilineText(drawContext.getDocument(), getOccupiedAreaBBox(), fieldName, "")
: PdfFormField.createText(drawContext.getDocument(), getOccupiedAreaBBox(), fieldName, "");
field.setFontSize(defaultFontSize - 1);
form.addField(field);
}
이는 iText를 사용자 정의 렌더러 클래스의 draw
방법이다.
생성 된 PDF 문서가 의도 한대로 작동합니다. Adobe Acrobat Reader에서 열어 편집 가능한 필드를 채우거나 저장 한 다음 다시 열 수 있습니다.
내 요구 사항 중 하나는 양식을 프로그래밍 방식으로 평면화 할 수있게하는 것입니다 (사람이 작성한 후 분명히) 그 후에 편집이 불가능하게됩니다.
나는이 코드를 사용하여이 작업을 수행 :
나는 PDF 리더 평탄화 된 PDF를 열 때PdfDocument pdf = ... // Read a PDF stream and get the document object
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, false);
form.flattenFields();
pdf.close()
지금 문제, 필드가 비어 있습니다.
좀 디버깅을했고, 나는 어도비 리더 (버전 XI)와 편집 (구원) 한 필드를 평평하게하려고하는 경우에만이 문제가 발생할 것 같습니다. 프로그래밍 방식으로 입력란을 수정하면 (예 : iText의 PdfFormField#setValue(String)
메서드를 사용하면 병합 된 PDF가 값을 잘 렌더링합니다.
Adobe Reader는 양식 필드의 일부 속성을 적절하게 병합하지 못하게 설정 한 것 같습니다. 실제로 사실입니까? 그 주위에 어떤 방법이 있습니까?
는 ---------------------- 당신에게
---------------- EDIT 감사
분명히이 문제는 Adobe Reader에서 발생합니다. 어떤 이유로 /XObject
하위 유형없이 필드 정의를 저장하며 iText7은 form.flattenFields()
메소드를 검사합니다. <</BBox [0.0 0.0 523.0 109.0 ] /Filter /FlateDecode /Length 107 /Resources <</Font <</F1 21 0 R >> >> >>
당신이 /Subtype
일부가 누락 볼 수 있듯이 : Acrobat Reader가에 의해 저장된 <</BBox [0 0 523 109 ] /Filter /FlateDecode /Length 95 /Matrix [1 0 0 1 0 0 ] /Resources <</Font <</F1 23 0 R >> >> /Subtype /Form /Type /XObject >>
:
iText7에 의해 생성 :
이 필드 문자열 이클립스 디버거에서 같이 무엇인가 . 양식 입력란을 사용 중지 할 때마다 (예 : PdfAcroForm#flattenFields()
또는 PdfFormField#setReadOnly(boolean)
는 iText를이 코드와 PdfCanvas
에 대한 내용을 다시 그리기를 시도합니다 리더 필드가 더이상 /XObject
하지 않기 때문에, 생략됩니다
if(xObject != null && xObject.getPdfObject().get(PdfName.Subtype) != null) {
[...]
canvas.addXObject(xObject, ...);
}
.
내 해결 방법은 현재 새 것으로 필드를 대체하는 것입니다 :
Map<String,PdfFormField> fields = form.getFormFields();
Set<String> keys = new HashSet<>(fields.keySet()); // avoids concurrent modifications
for(String fieldName : keys) {
PdfFormField field = fields.get(fieldName);
PdfDictionary fieldObject = field.getPdfObject();
PdfFormField newField = field.isMultiline()
? PdfFormField.createMultilineText(pdf, fieldObject.getAsRectangle(PdfName.Rect), fieldName,
field.getValueAsString(), defaultFont, defaultFontSize)
: PdfFormField.createText(pdf, fieldObject.getAsRectangle(PdfName.Rect), fieldName,
field.getValueAsString(), defaultFont, defaultFontSize);
form.replaceField(fieldName, newField);
}
form.flattenFields();
그것은 종류의 글꼴 정보가 동적으로 설정되지 않은 경우에도 작동하지만이 another story입니다.