javaspring-bootcloudinary

How to upload and download document files (Excel, DOCX, PDF,...) to Cloudinary and get the url to view and download the correct file?


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


Solution

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