2010-11-26 4 views
1

나는 수백 개의 필드를 가진 PDF 문서를 가지고있다. 필드 이름은 모두 같은 "page1.line1.something"itextsharp와 관련된 문제

나는이 기간을 제거하고있는 듯 모든

의 밑줄 또는 (더 나은) 아무것도 중 하나로 교체 할로의 기간을 가지고 이 작동하지 않음 다음은 (항상 false를 반환) 때문에 필드가에 마침표가없는 경우,

Dim formfields As AcroFields = stamper.AcroFields 
Dim renametest As Boolean 
renametest = formfields.RenameField("page1.line1.something", "page1_line1_something") 

을 필드 기간이있는 경우 renamefield 방법은 작동하지 않습니다 itextsharp 라이브러리에서 버그가 수, 그것은 잘 작동합니다.

아무도이 문제를 발견하지 못했으며 해결 방법이 있습니까?

답변

1

이것은 AcroForm 양식입니까? 아니면 LiveCycle Designer (xfa) 양식입니까?

iText는 XFA (필드 이름이 지정되어있을 가능성이 높습니다) 인 경우 도움을 줄 수 없습니다. XFA로 작업 할 때만 필드 값을 가져 오거나 설정할 수 있습니다.

좋아, AcroForm. 소스에서 사용 된 경로를 이동하는 대신 기존 필드 사전 및 acroForm 필드 목록을 직접 조작하는 것이 좋습니다.

는 나는이 iText에 올 때 당신은 어떤 번역을해야 할 것이다, 그래서 자바 네이티브 해요,하지만 여기 간다 :

A)를 AcroForm의 필드 배열을 삭제합니다. 계산 순서는 그대로 (/ CO) 그대로 둡니다. 나는 생각한다.

PdfDictionary acroDict = reader.getCatalog().getAsDictionary(PdfName.ACROFORM); 
acroDict.remove(PdfName.FIELDS); 

B) 모든 '최상위'필드를 새로운 FIELDS 배열에 연결하십시오.

PdfArray newFldArray = new PdfArray(); 
acroDict.put(newFldArray, PdfName.FIELDS); 

// you could wipe this between pages to speed things up a bit 
Set<PdfIndirectReference> radioFieldsAdded = new HashSet<PdfIndirectReference>(); 

int numPages = reader.getNumberOfPages(); 
for (int curPg = 1; curPg <= numPages; ++curPg) { 
    PdfDictionary curPageDict = reader.getPageN(curPg); 
    PdfArray annotArray = curPageDict.getAsArray(PdfName.ANNOTS); 
    if (annotArray == null) 
    continue; 

    for (int annotIdx = 0; annotIdx < annotArray.size(); ++annotIdx) { 
    PdfIndirectReference fieldReference = (PdfIndirectReference) annotArray.getAsIndirect(annotIdx); 
    PdfDictionary field = (PdfDictionary)PdfReader.getObject(fieldReference); 

    // if it's a radio button 
    if ((PdfFormField.FF_RADIO & field.getAsNumber(PdfName.FF).intValue()) != 0) { 
     fieldReference = field.get(pdfName.PARENT); 
     field = field.getAsDict(PdfName.PARENT); // looks up indirect reference for you. 

     // only add each radio field once. 
     if (radioFieldsAdded.contains(fieldReference)) { 
     continue; 
     } else { 
     radioFieldsAdded.add(fieldReference); 
     } 
    } 

    field.remove(PdfName.PARENT); 

    // you'll need to assemble the original field name manually and replace the bits 
    // you don't like. Parent.T + '.' child.T + '.' + ... 
    String newFieldName = SomeFunction(field); 
    field.put(PdfName.T, new PdfString(newFieldName)); 

    // add the reference, not the dictionary 
    newFldArray.add(fieldReference) 
    } 
} 

C)

reader.removeUnusedObjects(); 

단점을 정리 :
더 많은 작업을.

모든 파일 형식을 변경하지는 않습니다. 적은 CPU & 메모리.

기존 코드는 필드 스크립트, 모든 필드 플래그 (읽기 전용, 숨김, 필수, 여러 줄 문자 등), 목록/콤보, 라디오 버튼 및 기타 몇 가지 다른 옵션을 무시합니다.

+0

XFA 형식이 아닙니다. –

+0

도움 주셔서 감사합니다. 늦어서 죄송합니다. –

1

필드 이름에 마침표를 사용하면 마지막 부분 만 이름을 바꿀 수 있습니다 (예 : 뭔가 "단지"이름을 바꿀 수 있습니다. 은 "PAGE1"과 "1 호선"나는이 계층을 삭제하고

에 의해 평탄화 된 구조

내가 이런 짓을로 교체하는 데 필요한

은 "뭔가"필드에 부모로 어도비에 의해 처리되기 때문입니다 내 (pdfstamper) 문서의 필드 계층 구조를 삭제 배열

  • 에 나는 각 필드에 필요한 주석을 읽고 각 필드
  • 에 대한 pdfdictionary 객체를 생성
    1. ,691 당신은 내가 그것을 어떻게보고 싶다면
    2. 나는이에 대한 몇 가지 sample code을 만든

    내 배열 데이터의 필드의 새로운 세트를 작성.