Поврежденный файл Excel при отправке его по электронной почте в формате Android из URI с использованием API Gmail - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь поделиться из приложения Microsoft Excel Android с моим пользовательским Android приложением, которое возьмет общую книгу Excel и отправит ее по электронной почте через API Gmail.

После отправки моего приложения письмо, и я пытаюсь открыть файл excel на своем компьютере, я получаю сообщение об ошибке: «Мы обнаружили проблему с некоторым содержимым в '25 мая xlsx'».

Однако он открывается в настольный Chrome браузер с использованием Google Sheets.

Вот Uri книги: content: //com.microsoft.office.excel.excelApplication.provider/docsui_temp_share_files/fea009cf-65c3-46f4-8dda-50758298b9fc/ May% 2025.xlsx

Вот код, который превращает его в файл.

Context ctx; //defined by Android
Uri uri; //comes in populated with the value above
String filename; //generated from the Uri in a separate method

InputStream is = ctx.getContentResolver().openInputStream(uri);
File directory = ctx.getCacheDir();
FileOutputStream fos = null;
File fileToReturn = null;
try {
    final File tempFile = File.createTempFile(filename.split("\\.")[0], "." + filename.split("\\.")[1], directory);
    tempFile.deleteOnExit();

    fos = new FileOutputStream(tempFile);

    byte[] bytes = new byte[1024 * 16];
    int read = -1;
    while ((read = is.read(bytes)) != -1) {
        fos.write(bytes);
    }

    fileToReturn = tempFile;

}
finally {
    if (fos != null) {
        fos.close();
    }
}

Вот код, который создает MimeMessage для отправки. Параметр вложений содержит файл, созданный сверху.

private MimeMessage createEmail(List<String> toAddresses,
                                String from,
                                String subject,
                                String bodyText, ArrayList<File> attachments) throws MessagingException {
    if(attachments == null){
        attachments = new ArrayList<>();
    }
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);

    MimeMessage email = new MimeMessage(session);
    InternetAddress fAddress = new InternetAddress(from);

    for(String toAddress : toAddresses) {
        InternetAddress toInternetAddress = new InternetAddress(toAddress);
        email.addRecipient(javax.mail.Message.RecipientType.TO, toInternetAddress );
    }

    email.setFrom(fAddress);
    email.setSubject(subject);

    Multipart multipart = new MimeMultipart();

    BodyPart textBody = new MimeBodyPart();
    textBody.setText(bodyText);
    multipart.addBodyPart(textBody);

    for (File attachment : attachments){
            MimeBodyPart attachmentBody = new MimeBodyPart();
            DataSource source = new FileDataSource(attachment.getAbsolutePath());
            attachmentBody.setDataHandler(new DataHandler(source));
            attachmentBody.setFileName(attachment.getName());
            multipart.addBodyPart(attachmentBody);
    }

    email.setContent(multipart);
    return email;
}

И код для отправки электронного письма.

private String sendMessage(Gmail service,
                           String userId,
                           MimeMessage email)
        throws MessagingException, IOException {

    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    email.writeTo(bytes);

    ByteArrayContent messageByteArrayContent = new ByteArrayContent("message/rfc822", bytes.toByteArray());
    
    Message message;
    message = service.users().messages().send(userId, null, messageByteArrayContent).execute();
}

Вот что приходит в виде электронного письма.

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_0_262386509.1596398610889"
Date: Sun, 2 Aug 2020 13:03:34 -0700

------=_Part_0_262386509.1596398610889
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

May 252265647717182285060.xlsx
------=_Part_0_262386509.1596398610889
Content-Type: application/octet-stream; name="May 25.xlsx"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="May 25.xlsx"


------=_Part_0_262386509.1596398610889--

Обратите внимание, что Content-Type - это application / octect-stream.

Я сделал это application / vnd.openxmlformats-officedocument.spreadsheetml.sheet, вручную добавив заголовок Content-Type, но чтобы безрезультатно.

Этот код подходит для отправки почти всего остального. И если я сначала сохраню файл excel и поделюсь им из моего приложения файлового менеджера, он откроется нормально.

И кажется, что c указывает на файл excel. Если я поделюсь им как pdf из приложения Excel (это вариант), pdf откроется нормально.

Я также сталкиваюсь с той же ошибкой, если пытаюсь поделиться из приложения Google Sheets и делюсь им как .xlsx файл. Но опять же, если я попытаюсь поделиться им как чем-либо еще, например .csv или .pdf, он отлично откроется с другой стороны.

Вот письмо, если оно опубликовано как файл .pdf из Google Таблиц приложение. Опять же, тип содержимого - application / octet-stream, но здесь он открывается нормально.

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_4_203349844.1596399067869"
Date: Sun, 2 Aug 2020 13:11:10 -0700

------=_Part_4_203349844.1596399067869
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Untitled spreadsheet8410545067288443069.pdf
------=_Part_4_203349844.1596399067869
Content-Type: application/octet-stream; name="Untitled spreadsheet8410545067288443069.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Untitled spreadsheet8410545067288443069.pdf"


------=_Part_4_203349844.1596399067869--

1 Ответ

0 голосов
/ 03 августа 2020

В коде, в котором вы пишете файл xlsx, вы всегда читаете указанный размер буфера (1024 * 16) и записываете в файл. Я думаю, что при последнем чтении, если байты, которые вы читаете, меньше размера буфера вашего массива байтов, вы будете писать лишние ненужные байты. Это может быть причиной повреждения вашего файла.

...