SpringBoot io stream exports Excel stored under Resource

Excel to stream, download. Locally, the server reports:

Problem 1: FileNotFoundException (The filename, directory name, or volume label syntax is incorrect.)

java.io.FileNotFoundException: file:\E:\liziyi\guopei6\gp6-exam\target\gp6-exam-0.0.1-SNAPSHOT.jar!\BOOT-INF\classes!\exceltemplate\exam_record_import_template.xls (filename , directory name or volume label syntax is incorrect.)

The source code reports the above error, because the server needs to make a jar package and run it. Using getResourceAsStream() to query the file address will report an error:

 public String download(String fileName, String folder, HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        try {
            String path = this.getClass().getClassLoader().getResource(folder + "/" + fileName).getPath();
            InputStream inputStream = new FileInputStream(new File(path));
            OutputStream os = response.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
            // 这里主要关闭。
            os.close();

            inputStream.close();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

Solution:

Because the jar is a compressed package, getResourceAsStream should be used instead of getResource

public String download(String fileName, String folder, HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        try {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(folder + "/" + fileName);
            OutputStream os = response.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
            // 这里主要关闭。
            os.close();

            inputStream.close();
        } catch (FileNotFoundException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

问题二:getOutputStream() has already been called for this response

Translation: getOutputStream() has been called for this response or: response.getOutputStream() has been used and cannot be used again.

But when running, it is found that it is caused by a null pointer, which has nothing to do with the two methods checked in the following figure. 

Then solve this.getClass().getClassLoader().getResourceAsStream (why get null

Question 3: this.getClass().getClassLoader().getResourceAsStream() gets the value of Null

The first thing to consider is why the fetched file is null.

1. The method causes the error

First, I suspect that the method is wrong. After all, there are n ways to export files with streams. Here is the definition from the online query:

1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源。 

2.Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源。 

I don't understand it, it's fine

2. The location causes the error

My local Excel file is placed in the Exam module, the method of downloading Excel is placed in the model module, the Lms, Order and Exam modules call the model module, and then go to the exam module to get the file to download.

Now the exam module test can get the file, other modules cannot. Because there are no other modules in the file, an error is reported.

Later, move the excel from the exam module to each module, so that the class gets the excel file from this module. Really solved the problem. As shown below:

To be added:

Excel, generate first, then download

excel download file using multithreading and redis

Guess you like

Origin blog.csdn.net/Ciel_Y/article/details/123376492