Java – use pdfbox 1.8 8 visual signature

I'm trying to use visual signatures and pdf@R_486_2419 @Make PDF I have two streams, it seems pdf@R_486_2419 @Only files can be processed Without three temporary files, I didn't try to make it work I can see from here that the API has changed, but it still handles files

public void signPdf(InputStream originalPdf,OutputStream signedPdf,InputStream image,float x,float y,String name,String location,String reason) {

    File temp = null;
    File temp2 = null;
    File scratchFile = null;
    RandomAccessFile randomAccessFile = null;
    OutputStream tempOut = null;
    InputStream tempIn = null;
    try {
        /* Copy original to temporary file */
        temp = File.createTempFile("signed1",".tmp");
        tempOut = new FileOutputStream(temp);
        copyStream(originalPdf,tempOut);
        tempOut.close();

        /* Read temporary file to second temporary file and stream */
        tempIn = new FileInputStream(temp);
        temp2 = File.createTempFile("signed2",".tmp");
        tempOut = new FileOutputStream(temp2);
        copyStream(tempIn,tempOut);
        tempIn.close();
        tempIn = new FileInputStream(temp2);

        scratchFile = File.createTempFile("signed3",".bin");
        randomAccessFile = new RandomAccessFile(scratchFile,"rw");

        /* Read temporary file */
        PDDocument document = PDDocument.load(temp,randomAccessFile);
        document.getCurrentAccessPermission().setCanModify(false);

        PDSignature signature = new PDSignature();
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
        signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
        signature.setName(name);
        signature.setLocation(location);
        signature.setReason(reason);
        signature.setSignDate(Calendar.getInstance());

        PDVisibleSignDesigner signatureDesigner = new PDVisibleSignDesigner(
                document,image,document.getNumberOfPages());
        signatureDesigner.xAxis(250).yAxis(60).zoom(-90).signatureFieldName("signature");

        PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
        signatureProperties.signerName(name).signerLocation(location)
                .signatureReason(reason).preferredSize(0).page(1)
                .visualSignEnabled(true).setPdVisibleSignature(signatureDesigner)
                .buildSignature();

        SignatureOptions options = new SignatureOptions();
        options.setVisualSignature(signatureProperties);

        document.addSignature(signature,dataSigner,options);

        /* Sign */
        document.saveIncremental(tempIn,tempOut);
        document.close();
        tempIn.close();

        /* Copy temporary file to an output stream */
        tempIn = new FileInputStream(temp2);
        copyStream(tempIn,signedPdf);
    } catch (IOException e) {
        logger.error("PDF signing failure",e);
    } catch (COSVisitorException e) {
        logger.error("PDF creation failure",e);
    } catch (SignatureException e) {
        logger.error("PDF signing failure",e);
    } finally {
        closeStream(originalPdf);
        closeStream(signedPdf);
        closeStream(randomAccessFile);
        closeStream(tempOut);
        deleteTempFile(temp);
        deleteTempFile(temp2);
        deleteTempFile(scratchFile);
    }
}

private void deleteTempFile(File tempFile) {
    if (tempFile != null && tempFile.exists() && !tempFile.delete()) {
        tempFile.deleteOnExit();
    }
}

private void closeStream(Closeable is) {
    if (is!= null) {
        try {
            is.close();
        } catch (IOException e) {
            logger.error("failure",e);
        }
    }
}

private void copyStream(InputStream is,OutputStream os) throws IOException {
    byte[] buffer = new byte[1024];
    int c;
    while ((c = is.read(buffer)) != -1) {
        os.write(buffer,c);
    }
    is.close();
}

I didn't see any text on the signature except for the document madness The results are as follows:

This is what it looks like when I do something similar with the iText library

Why is the name, location and reason missing in the visual signature representation? How can I solve this problem?

Solution

Why is the name, location and reason missing in the visual signature representation?

They weren't there because they didn't draw

IText indicates that the default way of visual signature is to add this information to the visualization

PDF@R_486_2419 @'pdvisiblesigbuilder indicates that the default way of visual signature is to have no such information

It is neither wrong nor correct, both are just default values

People should look for the normative place of this information. After all, it is the signature group

How can I solve this problem?

The actual content of signature visualization is defined by signatureproperties Pdvisiblesigbuilder instance creation during buildsignature():

public void buildSignature() throws IOException
{
    PDFTemplateBuilder builder = new PDVisibleSigBuilder();
    PDFTemplateCreator creator = new PDFTemplateCreator(builder);
    setVisibleSignature(creator.buildPDF(getPdVisibleSignature()));
}

Therefore, by replacing

signatureProperties.signerName(name).signerLocation(location)
            .signatureReason(reason).preferredSize(0).page(1)
            .visualSignEnabled(true).setPdVisibleSignature(signatureDesigner)
            .buildSignature();

In your code

signatureProperties.signerName(name).signerLocation(location)
            .signatureReason(reason).preferredSize(0).page(1)
            .visualSignEnabled(true).setPdVisibleSignature(signatureDesigner);

    PDFTemplateBuilder builder = new ExtSigBuilder();
    PDFTemplateCreator creator = new PDFTemplateCreator(builder);
    signatureProperties.setVisibleSignature(creator.buildPDF(signatureProperties.getPdVisibleSignature()));

For extsigbuilder, a custom version of the pdvisiblesigbuilder class, you can draw anything you want there, such as:

class ExtSigBuilder extends PDVisibleSigBuilder
{
    String fontName;

    public void createImageForm(PDResources imageFormResources,PDResources innerFormResource,PDStream imageFormStream,PDRectangle formrect,AffineTransform affineTransform,PDJpeg img)
            throws IOException
    {
        super.createImageForm(imageFormResources,innerFormResource,imageFormStream,formrect,affineTransform,img);

        PDFont font = PDType1Font.HELVETICA;
        fontName = getStructure().getImageForm().getResources().addFont(font);

        logger.info("Added font to image form: " + fontName);
    }

    public void injectAppearanceStreams(PDStream holderFormStream,PDStream innterFormStream,String imageObjectName,String imageName,String innerFormName,PDVisibleSignDesigner properties)
            throws IOException
    {
        super.injectAppearanceStreams(holderFormStream,innterFormStream,imageObjectName,imageName,innerFormName,properties);

        String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName + " Do Q\n";
        String text = "BT /" + fontName + " 10 Tf (Hello) Tj ET\n";
        appendRawCommands(getStructure().getImageFormStream().createOutputStream(),imgFormComment + text);

        logger.info("Added text commands to image form: " + text);
    }
}

Write "hello" in Helvetica, size 10, at the bottom left of the image form (the form actually displayed)

PS: in my opinion, the object - oriented structure behind this should be completely reformed

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>