Извлечь PDF-файл на AWS S3, используя iText Java - PullRequest
2 голосов
/ 29 января 2020

Я использую ниже iText Java код для извлечения вложений из файла PDF. это прекрасно работает в локальной системе. Он извлекает XML файл из PDF и сохраняет на strOutputPath. Я хочу выполнить эту операцию на AWS S3. Файл PDF будет на S3, а вложение должно быть извлечено на S3. Как я могу использовать абсолютный путь файла на S3 в этом случае. Я использовал s3client.getUrl (). ToExternalForm (); , но получаю ошибку HTTP 403.

import java.util.Iterator;
import java.util.Set;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.File;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfDictionary;
import java.io.IOException;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;

public class app
{
    public static void main(final String[] args) {
        try {
            final String strInputPath = args[0];
            final String strOutputPath = args[1];
            final PdfReader pdfReader = new PdfReader(strInputPath);
            final PdfDictionary catalog = pdfReader.getCatalog();

            final PdfDictionary names = catalog.getAsDict(PdfName.NAMES);
            final PdfDictionary embeddedFiles = names.getAsDict(PdfName.EMBEDDEDFILES);
            final PdfArray embeddedFilesArray = embeddedFiles.getAsArray(PdfName.NAMES);

            for (int i = 0; i < embeddedFilesArray.size(); ++i) {
                final PdfDictionary FileSpec = embeddedFilesArray.getAsDict(i);
                if (FileSpec != null) {
                    String strFileName = FileSpec.getAsString(PdfName.F).toString();
                    System.out.println(strFileName);
                    if (strFileName.endsWith(".xml")) {
                        strFileName = String.valueOf(System.currentTimeMillis()) + ".xml";
                        extractFiles(pdfReader, FileSpec, String.valueOf(strOutputPath) + strFileName);
                    }
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void extractFiles(final PdfReader pdfReader, final PdfDictionary filespec, final String strFileName) {
        final PdfDictionary refs = filespec.getAsDict(PdfName.EF);
        PRStream prStream = null;
        FileOutputStream outputStream = null;
        final Set<PdfName> keys = (Set<PdfName>)refs.getKeys();
        try {
            for (final PdfName key : keys) {
                prStream = (PRStream)PdfReader.getPdfObject((PdfObject)refs.getAsIndirectObject(key));
                outputStream = new FileOutputStream(new File(strFileName));
                outputStream.write(PdfReader.getStreamBytes(prStream));
                outputStream.flush();
                outputStream.close();
            }
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e2) {
            e2.printStackTrace();
        }
        finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            }
            catch (IOException e3) {
                e3.printStackTrace();
            }
        }
        try {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        catch (IOException e3) {
            e3.printStackTrace();
        }
    }
}

1 Ответ

0 голосов
/ 09 февраля 2020

Я думаю, что вам нужно написать клиент Java, который работает с файлами в вашей корзине S3 и выполняет следующие шаги:

  • Загружает требуемый файл из S3.
  • Извлекает вложение из файла.
  • Загружает полученные файлы обратно на S3.

Пример кода для выполнения вышеупомянутых шагов:

import java.io.*;
import java.util.Set;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.itextpdf.text.pdf.*;

public class S3PDFAttachmentExtractor {

    public static void main(String[] args) throws IOException {

    // download file from S3
    AmazonS3Client amazonS3Client = new AmazonS3Client();
    S3Object object = amazonS3Client.getObject("<yours3location>", "fileKey");

    // write the file content to a local file.
    S3ObjectInputStream objectContent = object.getObjectContent();
    FileOutputStream out = new FileOutputStream("tempOutputFile.pdf");
    writeToFile(objectContent, out);

    // Extract attachment from the downloaded file.
    extractAttachment("tempOutputFile.pdf", "tempAttachement.xml");

    //upload the attachment
    uploadFile("<s3bucket.fully.qualified.name>", "tempAttachement.xml", "attachementNameOnS3.xml");

    }

    private static void writeToFile(InputStream input, FileOutputStream out) throws IOException {
    // Read the text input stream one line at a time and display each line.
    try (BufferedInputStream in = new BufferedInputStream(input);) {
        byte[] chunk = new byte[1024];
        while (in.read(chunk) > 0) {
        out.write(chunk);
        }
    } finally {
        input.close();
    }
    }

    public static void extractAttachment(final String strInputPath, final String strOutputPath) {
    try {
        final PdfReader pdfReader = new PdfReader(strInputPath);
        final PdfDictionary catalog = pdfReader.getCatalog();
        final PdfDictionary names = catalog.getAsDict(PdfName.NAMES);
        final PdfDictionary embeddedFiles = names.getAsDict(PdfName.EMBEDDEDFILES);
        final PdfArray embeddedFilesArray = embeddedFiles.getAsArray(PdfName.NAMES);
        for (int i = 0; i < embeddedFilesArray.size(); ++i) {
        final PdfDictionary FileSpec = embeddedFilesArray.getAsDict(i);
        if (FileSpec != null) {
            String strFileName = FileSpec.getAsString(PdfName.F).toString();
            System.out.println(strFileName);
            if (strFileName.endsWith(".xml")) {
            strFileName = String.valueOf(System.currentTimeMillis()) + ".xml";
            extractFiles(pdfReader, FileSpec, String.valueOf(strOutputPath) + strFileName);
            }
        }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    }

    private static void extractFiles(final PdfReader pdfReader, final PdfDictionary filespec, final String strFileName) {
    final PdfDictionary refs = filespec.getAsDict(PdfName.EF);
    PRStream prStream = null;
    FileOutputStream outputStream = null;
    final Set<PdfName> keys = (Set<PdfName>) refs.getKeys();
    try {
        for (final PdfName key : keys) {
        prStream = (PRStream) PdfReader.getPdfObject((PdfObject) refs.getAsIndirectObject(key));
        outputStream = new FileOutputStream(new File(strFileName));
        outputStream.write(PdfReader.getStreamBytes(prStream));
        outputStream.flush();
        outputStream.close();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e2) {
        e2.printStackTrace();
    } finally {
        try {
        if (outputStream != null) {
            outputStream.close();
        }
        } catch (IOException e3) {
        e3.printStackTrace();
        }
    }
    try {
        if (outputStream != null) {
        outputStream.close();
        }
    } catch (IOException e3) {
        e3.printStackTrace();
    }
    }

    private static void uploadFile(String bucketFullPath, String fileLocation, String fileName) throws IOException {
    AmazonS3Client amazonS3Client = new AmazonS3Client();
    InputStream bis = new FileInputStream(fileLocation);
    ObjectMetadata objectMetadata = new ObjectMetadata();
    objectMetadata.setContentType("application/xml");
    amazonS3Client.putObject(bucketFullPath, fileName, bis, objectMetadata);
    }
}

Обратите внимание, , что лучший способ сделать это - написать AWS лямбда-функцию в Java, используя приведенный выше код. Поскольку AWS Lambada можно легко настроить для обработки событий из хранилища S3, ваш код будет автоматически вызываться при записи или изменении файла в корзине S3. Для получения более подробной информации вы можете проверить AWS Лямбда-документация

Редактировать : Другой вариант - если вы используете код Java на AWS EC2 , то есть способ смонтировать S3-контейнер как файловую систему . Это позволит вам получить доступ к файлам, как будто эти файлы хранятся локально, и ваш оригинальный код будет работать. Но этот подход будет работать только в среде AWS EC2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...