【问题标题】:Edit pdf file in AWS S3 bucket using iText使用 iText 在 AWS S3 存储桶中编辑 pdf 文件
【发布时间】:2017-10-19 04:08:39
【问题描述】:

AWS S3 存储桶有 1 个 pdf 文件。此 pdf 文件的内容需要使用 iText Java 库进行编辑。修改后的文件需要再次存储在 S3 存储桶中。目前,我们正在使用 AWS Lambda 函数。空 pdf 文件正在目标 s3 存储桶中创建,AWS cloudWatch 中出现错误消息:“管道已关闭”

Lambda java代码:

private String bucketName = "forms-storage";

public String getProposalPdf(InputRequest inputRequest, Context context) throws DocumentException, IOException{

    final BasicAWSCredentials awsCreds = new BasicAWSCredentials(ConstantValues.AccessKey, ConstantValues.SecretKey);
    final AmazonS3Client s3client = (AmazonS3Client) AmazonS3ClientBuilder.standard().withRegion(Regions.AP_SOUTH_1)
                    .withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();
    S3Object object = s3client.getObject(new GetObjectRequest(bucketName, "forms/COMBO ver 1.1.pdf"));
    InputStream objectData = object.getObjectContent();

    PdfReader reader;
    PdfStamper stamper = null;
    BaseFont bf;

    PipedOutputStream pdfBytes = new PipedOutputStream();

    try {           
        reader = new PdfReader(objectData);
        stamper = new PdfStamper(reader, pdfBytes);

        bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);

        PdfContentByte over = stamper.getOverContent(1);
        over.beginText();
        over.setColorFill(BaseColor.BLACK);
        over.setFontAndSize(bf, 12);
        over.setTextMatrix(120,717);
        over.showText("this is edited text");
        over.endText();

        PipedInputStream inputStream = new PipedInputStream(pdfBytes);

        ObjectMetadata meta = new ObjectMetadata();
        meta= object.getObjectMetadata();
        meta.setContentLength(inputStream.available());         

        s3client.putObject(new PutObjectRequest(bucketName, "forms/123.pdf", inputStream, meta));           

    } catch (IOException e) {
        e.printStackTrace();
    } catch (DocumentException e) {
        e.printStackTrace();
    } 
    finally
    {
        stamper.close();            
        objectData.close();
    }
    return "PDF Created";
}

【问题讨论】:

    标签: java amazon-web-services amazon-s3 lambda itext


    【解决方案1】:

    问题不在于 AWS 或 iText,而在于您处理 PipedInputStreamPipedOutputStream 的方式。

    特别是在调用stamper.close()时,大部分有价值的数据都写入了PDF,但是您在关闭压模之前设置了内容长度meta.setContentLength(inputStream.available());,因此长度无效。调用putObject 后,inputStream 实例被关闭(检查内部closedByReader 字段),但pdfBytes 仍然连接到它,并且在inputStream 关闭后无法写入它,所以当stamper.close(); 被调用时,你会得到一个例外,因为你不能再写信给inputStream

    我认为在当前方法中解决此问题的任何尝试都不够,因为在documentation 中明确指出

    通常,数据由一个线程从 PipedInputStream 对象读取,数据由其他线程写入相应的 PipedOutputStream。 不建议尝试在一个线程中同时使用这两个对象,因为这可能会使线程死锁

    因此,一种解决方案是使用ByteArrayOutputStreamByteArrayInputStream,尽管内存效率不高:

    ByteArrayOutputStream pdfBytes = new ByteArrayOutputStream();
    
    try {
        reader = new PdfReader(objectData);
        stamper = new PdfStamper(reader, pdfBytes);
    
        bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
    
        PdfContentByte over = stamper.getOverContent(1);
        over.beginText();
        over.setColorFill(BaseColor.BLACK);
        over.setFontAndSize(bf, 12);
        over.setTextMatrix(120,717);
        over.showText("this is edited text");
        over.endText();
    
        stamper.close();
        objectData.close();
    
        ObjectMetadata meta = new ObjectMetadata();
        meta= object.getObjectMetadata();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(pdfBytes.toByteArray());
        meta.setContentLength(inputStream.available());
    
        s3client.putObject(new PutObjectRequest(bucketName, "forms/123.pdf", inputStream, meta));      
    
    } catch (IOException e) {
        e.printStackTrace();
    } catch (DocumentException e) {
        e.printStackTrace();
    }
    

    通常 PDF 的大小不会太大,因此您可以让自己将它们存储在内存中。如果您想优化内存消耗,您应该在单独的线程中进行 PDF 处理。我建议查看this 文章或搜索使用PipedInputStreamPipedOutputStream 的通用示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-04
      • 2015-03-21
      • 2018-10-25
      • 1970-01-01
      • 2018-08-13
      • 2020-06-15
      • 1970-01-01
      相关资源
      最近更新 更多