2015-12-01 4 views
2

Я использую pdfbox-1.8.8, чтобы выполнить функцию подписания в PDF-файле.pdfbox - ошибка файла ландшафта

Он хорошо работает с PDF-файлом в портретном режиме. Но с ландшафтным файла У меня есть проблема

Position of signatory I want to sign

Result of the sign

Похоже, что координата неправильно для файла ландшафта.

Кто-нибудь знает, что не так в файле?

Вот ссылка на pdf file

Вот код, который я использовал, чтобы подписать

public void signDetached(String inputFilePath, String outputFilePath, String signatureImagePath, Sign signProperties) { 
    OutputStream outputStream = null; 
    InputStream inputStream = null; 
    PDDocument document = null; 
    InputStream signImageStream = null; 

    try { 
     setTsaClient(null); 
     document = PDDocument.load(inputFilePath); 
     // create signature dictionary 
     PDSignature signature = new PDSignature(); 
     signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); 
     signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED); 
     signature.setName("VANDUC1102"); 
     signature.setLocation(null); 
     String displayName = "Hello World, Document signed by VANDUC1102"; 
     String reason = reasonText+ " " + displayName; 
     signature.setReason(reason); 

     // the signing date, needed for valid signature 
     signature.setSignDate(Calendar.getInstance());    
     int signatureInPage = signProperties.getPageNumber() + 1; 
     signImageStream = new FileInputStream(new File(signatureImagePath)); 
     PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(inputFilePath, signImageStream, signatureInPage); 

     float xAxis = convertPixel2Point(signProperties.getX()) ; 
     float yAxis = convertPixel2Point(signProperties.getY());    
     float signImageHeight = convertPixel2Point(signImageHeight);  
     float signImageWidth = convertPixel2Point(signImageWidth); 

     visibleSig.xAxis(xAxis) 
       .yAxis(yAxis) 
       .zoom(0) 
       .signatureFieldName("Signature") 
       .height(signImageHeight) 
       .width(signImageWidth); 
     PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties(); 

     signatureProperties.signerName(eiUser.getName()) 
       .signerLocation(null) 
       .signatureReason(reason) 
       .preferredSize(0) 
       .page(signProperties.getPageNumber()) 
       .visualSignEnabled(true) 
       .setPdVisibleSignature(visibleSig) 
       .buildSignature(); 
     // register signature dictionary and sign interface 
     SignatureOptions signatureOptions = new SignatureOptions(); 
     signatureOptions.setVisualSignature(signatureProperties); 
     signatureOptions.setPage(signatureInPage); 
     document.addSignature(signature, this, signatureOptions); 

     File outputFile = new File(outputFilePath); 
     outputStream = new FileOutputStream(outputFile); 
     inputStream = new FileInputStream(inputFilePath); 
     IOUtils.copyStream(inputStream, outputStream); 
     document.saveIncremental(inputStream, outputStream); 
     outputStream.flush(); 
    } catch (COSVisitorException | SignatureException | IOException ex) { 
     log.error("signDetached ", ex); 
    } finally { 
     IOUtils.closeStream(outputStream); 
     IOUtils.closeStream(inputStream); 
     IOUtils.closeStream(signImageStream); 
     IOUtils.closeStream(document); 
    } 
} 
private float convertPixel2Point(float pixel){ 
    return pixel * (float) 72/96; 
} 

Как я уже говорил, этот код работает хорошо с портретной PDF

Спасибо.

+1

Скорее всего, страница имеет ориентированную на портретную систему координат и является ландшафтом только потому, что она также имеет значение ** Rotate **, указывающее на просмотр PDF-файлов, чтобы повернуть его для отображения. – mkl

+2

Действительно, каждый словарь страниц содержит запись '/ Rotate 90' (строки 484-519, если открыт как текст) – fabian

+1

Таким образом, OP должен принимать во внимание поворот при применении подписи. Поскольку он еще не показывал никакого кода, даже не объяснил, является ли «подпись» простым изображением или фактически заполненным сигнатурным полем AcroForm, очень спекулятивно говорить что-либо еще. – mkl

ответ

3

Эта страница имеет ненулевое значение Повернуть значение. Визуальные классы подписи PDFBox полностью игнорируют это значение, поэтому нужно дать ему координаты и размеры, как если бы страница не была повернута.

Это можно сделать, добавив следующее switch заявление:

float xAxis = convertPixel2Point(/*signProperties.getX()*/x) ; 
float yAxis = convertPixel2Point(/*signProperties.getY()*/y);    
float signImageHeight = convertPixel2Point(/*signImageHeight*/324);  
float signImageWidth = convertPixel2Point(/*signImageWidth*/309); 

int rotation = getPageRotation(inputFilePath, page) % 360; 
switch (rotation) 
{ 
case 0: 
    // all ok; 
    break; 
case 90: 
    visibleSig.affineTransformParams(new byte[] {0, 1, -2, 0, 100, 0}) 
       .formaterRectangleParams(new byte[]{0, 0, 100, 100}); 

    float temp = yAxis; 
    yAxis = visibleSig.getPageHeight() - xAxis - signImageWidth; 
    xAxis = temp; 

    temp = signImageHeight; 
    signImageHeight = signImageWidth; 
    signImageWidth = temp; 

    break; 
case 180: 
    // Implement in a similar fashion 
case 270: 
    // Implement in a similar fashion 
} 

visibleSig.xAxis(xAxis) 
      .yAxis(yAxis) 
      .zoom(0) 
      .signatureFieldName("Signature") 
      .height(signImageHeight) 
      .width(signImageWidth); 

и следующий метод:

private int getPageRotation(String documentPath, int page) throws IOException 
{ 
    try (PDDocument document = PDDocument.load(documentPath)) 
    { 
     List<?> pages = document.getDocumentCatalog().getAllPages(); 
     PDPage pageObject =(PDPage) pages.get(page); 
     return pageObject.getRotation(); 
    } 
} 

Для Поворот значений 180 и 270, аналогичные поправки должны быть сделаны ,

(Методы испытаний testLandscapeOriginal и testLandscapeFixed в SignLikeVanduc1102)

+0

Большое спасибо, я думаю, что код должен быть помещен в источник pdfbox, событие pdfbox2.0.0RC не поддерживало эту функцию. – vanduc1102

+0

* Я думаю, что код должен быть помещен в источник pdfbox * - Ну ... нет ... Я думаю, что код PDFBox должен быть действительно исправлен в этом отношении. Код выше просто обход ...;) – mkl

+0

Извините @mkl, я настолько глуп, что не могу найти документ для параметров '' 'visibleSig.affineTransformParams (новый байт [] {0, 1, - 2, 0, 100, 0}) .formaterRectangleParams (новый байт [] {0, 0, 100, 100}); '' '. Я хочу закончить дела * 180 * и * 270 *. – vanduc1102

2

Начиная с версии 2.0.5 (будет выпущен некоторое время весной 2017 года, snapshot available), регулируя поле подписи для повернутых страниц можно будет с adjustForRotation() вызова , В CreateVisibleSignature.java example, эта линия

visibleSignDesigner.xAxis(x).yAxis(y).zoom(zoomPercent); 

должен быть изменен на это:

visibleSignDesigner.xAxis(x).yAxis(y).zoom(zoomPercent).adjustForRotation(); 

Изменение (issue PDFBOX-3671) частично на основе ответа по @mkl. Он не будет доступен для 1.8. *.

Смежные вопросы