2012-10-25 2 views
5

PDFBox에 대한 문서로 정말 고심하고 있습니다. 그런 대중적인 도서관 정보를 위해 나는 땅에서 조금 얇은 것처럼 보인다 (나를 위해!).PDFBox를 사용하여 PDF 보호

어쨌든이 문제는 PDF 보호와 관련이 있습니다. 현재 내가 원하는 것은 사용자의 액세스 권한을 제어하는 ​​것입니다. 특히 나는 사용자가 PDF를 수정할 수 없도록하고 싶다.

액세스 권한 코드를 생략하면 모든 것이 완벽하게 작동합니다. 외부 리소스에서 PDF를 읽습니다. 그런 다음 필드를 읽고 채우고 새 PDF를 저장하기 전에 일부 이미지를 추가합니다. 그것은 모두 완벽하게 작동합니다. 나는 모든 텍스트를이 코드를 추가하고 이미지가 나가는 PDF에서 스트라이프 때

/* Secure the PDF so that it cannot be edited */ 
try { 
    String ownerPassword = "DSTE$gewRges43"; 
    String userPassword = ""; 

    AccessPermission ap = new AccessPermission(); 
    ap.setCanModify(false); 

    StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, userPassword, ap); 
    pdf.protect(spp); 
} catch (BadSecurityHandlerException ex) { 
    Logger.getLogger(PDFManager.class.getName()).log(Level.SEVERE, null, ex); 
} 

: 나는 액세스를 관리하려면 다음 코드를 추가 할 때

문제

온다. 필드는 여전히 문서에 있지만 모두 공백이며 원래 PDF의 일부이고 코드에서 동적으로 추가 된 모든 텍스트와 이미지가 사라집니다.

업데이트 : 좋아요, 문제가 양식 필드와 관련된 버그에서 비롯된 것 같습니다. 양식 필드가없는 다른 접근법을 시도하고 그것이 제공하는 것을 살펴볼 것입니다.

+0

공백을 반환하는 임의의 PDF와 동일한 문제가 발생합니다. 어떤 아이디어? – NightWolf

+0

나는이 문제의 밑바닥에 결코 도착하지 않았다. 결국 다른 라이브러리를 사용해야했습니다! – tarka

+0

감사합니다. 당신을위한 해결책을 찾았습니다. – NightWolf

답변

7

이 문제에 대한 해결책을 찾았습니다. PDF가 외부 소스에서 제공되는 경우 PDF가 보호되거나 암호화되는 경우가 있습니다.

외부 소스에서 PDF 문서를로드하고 보호 기능을 추가 할 때 빈 출력이 나오면 암호화 된 문서로 작업하고있는 것입니다. PDF 문서를 처리하는 스트림 처리 시스템이 있습니다. 그래서 다음 코드가 나에게 도움이된다. PDF 입력 작업 만하는 경우 아래 코드를 흐름과 통합 할 수 있습니다.

public InputStream convertDocument(InputStream dataStream) throws Exception { 
    // just acts as a pass through since already in pdf format 
    PipedOutputStream os = new PipedOutputStream(); 
    PipedInputStream is = new PipedInputStream(os); 

    System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768"); //for large files 

    PDDocument doc = PDDocument.load(dataStream, true); 

    if (doc.isEncrypted()) { //remove the security before adding protections 
     doc.decrypt(""); 
     doc.setAllSecurityToBeRemoved(true); 
    } 
    doc.save(os); 
    doc.close(); 
    dataStream.close(); 
    os.close(); 
    return is; 
} 

이제 리턴 된 InputStream을 보안 응용 프로그램에 사용하십시오.

PipedOutputStream os = new PipedOutputStream(); 
    PipedInputStream is = new PipedInputStream(os); 

    System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768"); 
    InputStream dataStream = secureData.data(); 

    PDDocument doc = PDDocument.load(dataStream, true); 
    AccessPermission ap = new AccessPermission(); 
    //add what ever perms you need blah blah... 
    ap.setCanModify(false); 
    ap.setCanExtractContent(false); 
    ap.setCanPrint(false); 
    ap.setCanPrintDegraded(false); 
    ap.setReadOnly(); 

    StandardProtectionPolicy spp = new StandardProtectionPolicy(UUID.randomUUID().toString(), "", ap); 

    doc.protect(spp); 

    doc.save(os); 
    doc.close(); 
    dataStream.close(); 
    os.close(); 

이제 빈 출력이없는 적절한 문서가 반환됩니다.

트릭은 먼저 암호화를 제거하는 것입니다!

+0

싱글 스레드 코드에서'PipedOutputStream'과'PipedInputStream'을 사용하는 것은 다소 기이합니다. – mkl

+0

죄송합니다. 이 예에서 pipedinputstream ref는 실제로 다른 스레드로 전달됩니다 (이 코드는 고정 된 akka 액터에 있습니다). 위의 코드에서 센드를 생략했습니다. – NightWolf

관련 문제