I am using Cloudinary to upload document files (like Excel, DOCX, PDF) in my Java Spring Boot application. However, when uploading, the returned URL does not allow downloading the file in the correct format. Instead, it returns a file with no format or that cannot be viewed after dowload.
I use the uploadSingleFileToFolder method to upload the file:
public String uploadSingleFileToFolder(MultipartFile file, String folderName) throws IOException, AppException {
if (file.getSize() > maxFileSize) {
throw new AppException("File size exceeds the maximum allowed size.");
}
if (!isContentTypeAllowed(file.getContentType())) {
throw new AppException("Unsupported file type: " + file.getContentType());
}
// Get the original filename
String originalFilename = file.getOriginalFilename();
if (originalFilename == null) {
throw new AppException("Invalid file name.");
}
// Remove the file extension for public_id
String filenameWithoutExtension = originalFilename.replaceAll("\\.[^.]+$", "");
// Upload the file with the correct resource_type
var options = ObjectUtils.asMap(
"folder", folderName,
"public_id", filenameWithoutExtension,
"use_filename", true,
"unique_filename", false,
"resource_type", "auto" // Set resource_type to "raw" for documents
);
var uploadResult = cloudinary.uploader().upload(file.getBytes(), options);
return uploadResult.get("secure_url").toString();
}
When I upload an Excel file (example.xlsx), the returned URL looks like this:
https://res.cloudinary.com/dndoreidh/raw/upload/v1740554207/project-document/example
When accessing this URL, the browser downloads a file without a format (for example, example instead of example.xlsx).
I'm using free plan Cloudinary.
I have tried all those thing but still not working:
Do you guys have any
When uploading "raw" files (i.e. non image/video/audio) to Cloudinary, the extension must be part of the public_id
. This would then be included in the url
and secure_url
fields you get in the response. For "image" and "video" resource_type
, the public_id
should not contain the extension.
One way to resolve it is if you pass originalFilename
as the public_id
in your options
instead of removing the extension there. Also, if you're passing the public_id
explicitly in your request, the use_filename
and unique_filename
are redundant and can be removed - they are only relevant if you're not explicitly telling Cloudinary what the public_id
should be.
However, that's not ideal as you then need to check in your code the type of file to decide whether to include the extension only for "raw" files.
What I recommend is removing the public_id
parameter from your options
and only keeping folder
, use_filename
, unique_filename
and resource_type
as you have them now. Since you're setting the public_id
as the name of the local file anyway, you can omit that and use_filename
and unique_filename
would take care of assigning this same value as the public_id
on Cloudinary side with the added benefit of automatically keeping the extension if the file is "raw" without you needing to do so.