使用Gmail API从Uri在Android中发送电子邮件时损坏了excel文件



我正在尝试从微软的Excel Android应用程序共享到我的自定义Android应用程序,该应用程序将接收共享的Excel工作簿并通过Gmail的API通过电子邮件发送。

在我的应用程序发送了电子邮件,我试图在电脑上打开excel文件后,我出现了错误,";我们在'May 25.xlsx'中发现了一些内容的问题;

然而,它确实使用谷歌表单在桌面Chrome浏览器中打开。

以下是工作簿的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的代码。attachments参数具有从上面创建的文件。

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--

请注意,内容类型是application/octect流。

我已经通过手动添加Content-Type标头创建了这个应用程序/vnd.openxmlformats-officedocument.spreadsheetml.sheet,但没有用。

这段代码几乎可以发送任何其他内容。如果我先保存excel文件,然后从我的文件管理器应用程序中共享,它会很好地打开。

它似乎是excel文件特有的。如果我从Excel应用程序中以pdf格式分享它(这是一个选项(,pdf会很好地打开。

如果我尝试从Google Sheets应用程序共享,并将其作为.xlsx文件共享,我也会遇到同样的错误。但是,如果我尝试将它作为其他任何东西共享,比如.csv或.pdf,它在另一边打开得很好。

这是一封来自Google Sheets应用程序的.pdf文件。同样,内容类型是application/octet流,但它在这里打开得很好。

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--

在编写xlsx文件的代码中,您总是读取指定的缓冲区大小(1024*16(,并写入文件。我认为在上次读取时,如果读取的字节小于字节数组的缓冲区大小,则会写入额外的不必要字节。这可能是文件损坏的原因。

相关内容

最新更新