FeignClient 跨服务上传文件、导出Excel

分为两个 project,service 提供上传、下载的基础服务。client 作为被外部调用的服务。

本文使用的 spring boot 版本 是 2.2.5.RELEASE。

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.5.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

service 服务

pom
使用的 lombok 简化 POJO,使用 easyexcel 导出 Excel。

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

FileController
只有两个方法upload()打印文本文件内容,返回文件名;download()导出 Excel。

@RestController
public class FileController {

    @PostMapping("/upload")
    public String upload(@RequestPart("file") MultipartFile file) throws IOException {

        InputStream inputStream = file.getInputStream();

        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
            while (true) {
                String s = bufferedReader.readLine();
                System.out.println(s);
                if (s == null) {
                    break;
                }

            }
        }
        return file.getOriginalFilename();
    }

    @GetMapping("/download")
    public void download(HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
    }

    private List<DownloadData> data() {
        List<DownloadData> list = new ArrayList<DownloadData>();
        for (int i = 0; i < 10; i++) {
            DownloadData data = new DownloadData();
            data.setString("字符串" + 0);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }
}

@Data
public class DownloadData {
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("日期标题")
    private Date date;
    @ExcelProperty("数字标题")
    private Double doubleData;
}

client 服务

pom
相比于 service 服务,需要多引入 openfeign 的依赖。spring-cloud 的版本为 Hoxton.SR2。

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

启动类 ClientApplication
需要添加@EnableFeignClients注解

@EnableFeignClients
@SpringBootApplication
public class ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }

}

FileFeignClient
本项目为了简化,没有使用注册中心,而是使用了@FeignClienturl属性直接指定了地址。

  • 上传文件时必须添加== consumes = “multipart/form-data”==
  • 导出文件的返回值必须为feign.Response
@FeignClient(name = "service", url = "127.0.0.1:8081")
public interface FileFeignClient {

    @PostMapping(value = "/upload", consumes = "multipart/form-data")
    String upload(@RequestPart("file") MultipartFile file);

    @GetMapping("download")
    Response download();
}

FileController

@Slf4j
@RestController
public class FileController {

    private final FileFeignClient fileFeignClient;

    public FileController(FileFeignClient fileFeignClient) {
        this.fileFeignClient = fileFeignClient;
    }

    @PostMapping("/upload")
    public String upload(@RequestPart("file") MultipartFile file) {
		// 直接调用 FileFeignClient
        return fileFeignClient.upload(file);
    }

    @GetMapping("/download")
    public void download(HttpServletResponse servletResponse) {
		// 先调用 FileFeignClient 获取 feign.Response
		// 然后将 feign.Response 的内容写入 HttpServletResponse
        Response response = fileFeignClient.download();

        Response.Body body = response.body();
        for(Object key : response.headers().keySet()){
            List<String> kList = (List)response.headers().get(key);
            for(String val : kList){
                servletResponse.setHeader(key.toString(), val);
            }
        }

        try (InputStream inputStream = body.asInputStream();
             OutputStream outputStream = servletResponse.getOutputStream()) {
            byte[] b = new byte[inputStream.available()];
            inputStream.read(b);
            outputStream.write(b);
            outputStream.flush();
        } catch (IOException e) {
            log.error("导出Excel失败", e);
        }
    }
}

问题:k8s 导出 Excel 报字体相关的错

原因是 Alpine 镜像没有 Excel 需要的字体。
解决办法一行 Run… 安装字体

from ...
RUN apk add --update font-adobe-100dpi ttf-dejavu fontconfig
add ...

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值