java纯代码导出文件为压缩包

文章描述了一个Java开发中的功能,即通过Controller层处理下载压缩包的请求,从数据库获取文件列表,创建临时文件,使用ZipOutputStream进行文件压缩,并支持EasyExcel进行Excel数据导出。服务层详细展示了文件操作和压缩流程,包括文件下载、临时文件处理和响应头设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天做需求突然看到之前产品提的需求,导出多个文件为压缩包。功能部分早就已经完成了,想到还没有过类似的记录,今天就记录下来吧,是记录也是学历,如果有不对的地方还请多多指教。以下贴出的代码是下载压缩包的源代码,我的文件资源是存储在服务器根目录下,表中记录的文件存储的绝对路径,通过路径反查获取资源下载,看官可根据自己项目的情况判断是否适用你当下的需求场景。废话不多说,直接上代码:
controller层:

/**
     * 下载压缩包
     * @param request
     * @param response
     * @param idDTO 传入文件id
     */
    @SneakyThrows
    @PostMapping("/download-zip")
    @ApiOperation(value = "下载文件为压缩包")
    public SwaggerAjaxResult downloadFileZip(HttpServletRequest request, HttpServletResponse response, @RequestBody @Valid UpdateFileDTO idDTO){
        return SwaggerAjaxResult.success(inspectionProblemService.downloadFileZip(request,response,idDTO.getId()));
    }

service 层代码:

/**
     * 下载文件为压缩包
     *
     * @param request
     * @param response
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SwaggerAjaxResult downloadFileZip(HttpServletRequest request, HttpServletResponse response, String id) {
        try {
            List<TFile> fileVOList = fileService.lambdaQuery()
                    .eq(TFile::getParentId, id)
                    .eq(TFile::getParentTable, PROBLEM_TABLE_NAME)
                    .eq(TFile::getType, WJXX)
                    .list();
            Assert.notNull(fileVOList, "文件为空!");

            String fileName = super.baseMapper.getFileName(id);
            Assert.notNull(fileName, "文件名不能为空!");
            //创建临时路径,存放压缩文件
            String zipFilePath = System.getProperty("user.dir") + File.separator + "downloadZip" + File.separator;
            log.info("文件临时路径为:{}", zipFilePath);
            //如果文件不存在创创建新文件
            File zipFile = new File(zipFilePath);
            if (!zipFile.exists()) {
                zipFile.mkdirs();
            }
            //在临时文件夹里创建临时文件
            String temporaryZipName = zipFilePath + "临时存放.zip";
            //如果不存在就新创建一个
            File zipFiles = new File(temporaryZipName);
            if (!zipFiles.exists()) {
                zipFiles.createNewFile();
            }

            //压缩输出流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(temporaryZipName));
            //将文件写入压缩包
            for (TFile file : fileVOList) {
                writingFilesToZip(zipFilePath, zipOut, file, request);
            }
            //压缩完成关闭压缩流
            zipOut.close();
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8") + ".zip");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            ServletOutputStream outputStream = response.getOutputStream();
            FileInputStream inputStream = new FileInputStream(temporaryZipName);
            IOUtils.copy(inputStream, outputStream);
            //关闭输入流
            inputStream.close();
            //下载完成,删除临时文件
            File file = new File(zipFilePath);

            FileUtils.deleteFile(file);
            log.info("下载zip成功!");
            return SwaggerAjaxResult.success("下载zip成功!");
        } catch (IOException e) {
            e.printStackTrace();
            log.warn("下载zip失败!{}", e.getMessage());
            return SwaggerAjaxResult.error("下载zip失败!{}", e.getMessage());
        }
    }
/**
     * @param zipFilePath
     * @param zipOut
     * @param fileVO
     */
    private void writingFilesToZip(String zipFilePath, ZipOutputStream zipOut, TFile fileVO, HttpServletRequest request) throws IOException {
        String savePath = fileVO.getFileLink();
        //通过URL将文件下载至本地
        downLoadFromUrl(savePath, zipFilePath, fileVO.getFileName(), request);
        byte[] buf = new byte[2 * 1024];
        String srcDir = zipFilePath + fileVO.getFileName();
        File sourceFile = new File(srcDir);
        zipOut.putNextEntry(new ZipEntry(fileVO.getFileName()));
        int len;
        FileInputStream in = new FileInputStream(sourceFile);
        while ((len = in.read(buf)) != -1) {
            zipOut.write(buf, 0, len);
        }
        zipOut.closeEntry();
        in.close();

    }
private void downLoadFromUrl(String savePath, String zipFilePath, String fileName, HttpServletRequest request) throws IOException {
        File file1 = new File(savePath);
        byte[] getData = new byte[0];
        try {
            getData = org.apache.commons.io.FileUtils.readFileToByteArray(file1);
        } catch (IOException e) {
            log.warn("文件:{}不能访问!", savePath);
        }
        //文件保存位置
        File saveDir = new File(zipFilePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }

        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        fos.close();
    }

– 2024-02-22更新
用java包里面的方法导出压缩包

//导出压缩包文件名称
response.setHeader("Content-disposition", "attachment;filename="
                    + DateUtil.parseDate(reqParam.getStartTime()).toString(DatePattern.PURE_DATE_PATTERN) + "-"
                    + DateUtil.parseDate(reqParam.getEndTime()).toString(DatePattern.PURE_DATE_PATTERN)
                    + URLEncoder.encode("xxxx管理信息", "UTF-8") + ".zip");
            ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
            //groupByDate为将要导出的文件数据,我这里是按照数据的日期分组了,按日期数据为一个excel导出,最后组成一个压缩包
            try {
                for (Map.Entry<String, List<GrainReserveInfoVO>> entry : groupByDate.entrySet()) {
                    String key = entry.getKey();
                    AtomicInteger serialNo = new AtomicInteger(1);
                    entry.getValue().forEach(temp -> temp.setSerialNo(serialNo.getAndIncrement()));
                    ExcelWriter excelWriter = EasyExcel.write()
                            .excelType(ExcelTypeEnum.XLSX)
                            .autoCloseStream(Boolean.FALSE)
                            .registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, bodyStyle))
                            .build();
                    WriteSheet writeSheet = EasyExcel.writerSheet(key.substring(5, 7) + "月" + key.substring(8) + "日").build();
                    WriteTable writeTable = EasyExcel.writerTable(0).head(GrainReserveInfoVO.class).needHead(Boolean.TRUE).build();
                    excelWriter.write(entry.getValue(), writeSheet, writeTable);
                    //压缩包里每一个文件名称设置
                    ZipEntry zipEntry = new ZipEntry(DateUtil.parseDate(key).toString(DatePattern.PURE_DATE_PATTERN) + "xxxx管理信息.xlsx");
                    zipOutputStream.putNextEntry(zipEntry);
                    Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
                    workbook.write(zipOutputStream);
                }
                zipOutputStream.flush();
            } catch (Exception e) {
                log.error("导出xxxx失败", e);
                throw new CustomException("导出xxxx异常");
            } finally {
                //关闭数据流,注意关闭的顺序
                zipOutputStream.close();
                outputStream.close();
            }

如有不足,请多多指教!

<think>嗯,用户想用Java读取文件属性并导出为压缩的SHP文件。我需要先理清楚步骤。首先,SHP文件是GIS常用的格式,通常需要Shapefile库,比如GeoTools。然后,用户提到导出压缩包,可能需要将生成的SHP文件和相关文件(如.shp, .dbf, .shx等)打包成ZIP。 根据引用[2]和[5],GeoTools可以处理SHP的读写和坐标系统。用户需要读取文件属性,可能是指读取现有文件的属性,或者从其他数据源生成属性。然后导出到SHP,并压缩成ZIP。 步骤应该是:1. 使用GeoTools创建FeatureType,定义属性和几何类型。2. 创建Feature实例,填充数据。3. 写入到Shapefile。4. 将生成的文件打包成ZIP,可能需要用Java的ZipOutputStream。 另外,引用[2]提到处理ZIP压缩包直读,但这里用户需要导出压缩包,所以解压的逆过程,即压缩。需要注意临时文件的处理,避免脏文件,可以用临时目录或者内存操作,但SHP文件可能较大,用临时目录更实际。 用户可能需要示例代码,所以需要提供创建Feature、写入Shapefile,然后压缩的代码片段。同时,要处理坐标系统,比如引用[5]中的投影问题,可能需要设置正确的CRS。 可能的问题:文件路径处理,确保所有必要文件(.shp, .dbf等)都被正确写入和压缩。GeoTools的依赖配置,用户可能需要添加Maven依赖。 总结步骤:配置GeoTools依赖,创建数据模型,写入Shapefile,收集所有生成的文件,用ZipOutputStream压缩成ZIP,清理临时文件。</think>### 使用Java读取文件属性并导出压缩SHP文件的实现步骤 #### 一、技术选型与依赖准备 1. **核心库选择**: - **GeoTools**:GIS数据处理核心库,支持SHP文件读写、坐标系转换[^2][^5] - **Java内置压缩库**:`java.util.zip`处理ZIP压缩包 2. **Maven依赖配置**: ```xml <dependency> <groupId>org.geotools</groupId> <artifactId>gt-shapefile</artifactId> <version>25.1</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-epsg-hsql</artifactId> <version>25.1</version> </dependency> ``` #### 二、核心实现流程 $$ \begin{aligned} &\text{1. 定义数据结构} \rightarrow \text{2. 创建Feature集合} \\ &\rightarrow \text{3. 写入Shapefile} \rightarrow \text{4. 压缩为ZIP} \end{aligned} $$ #### 三、完整代码示例 ```java // 1. 创建FeatureType定义 SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder(); typeBuilder.setName("Location"); typeBuilder.setCRS(DefaultGeographicCRS.WGS84); // 坐标系设置[^5] typeBuilder.add("geometry", Point.class); typeBuilder.add("name", String.class); typeBuilder.add("id", Integer.class); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); // 2. 创建Feature集合 SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType); List<SimpleFeature> features = new ArrayList<>(); featureBuilder.add(new GeometryFactory().createPoint(new Coordinate(116.40, 39.90))); featureBuilder.add("北京地标"); featureBuilder.add(1); features.add(featureBuilder.buildFeature("point1")); // 3. 写入临时目录 File tempDir = Files.createTempDirectory("shp_export").toFile(); File shpFile = new File(tempDir, "output.shp"); FeatureCollection<SimpleFeatureType, SimpleFeature> collection = new ListFeatureCollection(featureType, features); try (ShapefileDataStore dataStore = new ShapefileDataStore(shpFile.toURI().toURL())) { dataStore.createSchema(featureType); try (FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriterAppend()) { for (SimpleFeature feature : collection) { SimpleFeature newFeature = writer.next(); newFeature.setAttributes(feature.getAttributes()); writer.write(); } } } // 4. 压缩为ZIP try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream("output.zip"))) { for (File file : tempDir.listFiles()) { zipOut.putNextEntry(new ZipEntry(file.getName())); Files.copy(file.toPath(), zipOut); zipOut.closeEntry(); } FileUtils.deleteDirectory(tempDir); // 清理临时文件[^2] } ``` #### 四、关键优化点 1. **内存管理**:使用临时目录避免内存溢出[^2] 2. **坐标系处理**:通过`setCRS()`指定投影系统(如CGCS2000)[^5] 3. **异常处理**:应添加try-with-resources确保资源释放
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值