PHP 百万数据导出生成压缩包下载

本文介绍了如何使用PHP处理大量数据,通过分批查询避免内存溢出,将数据导出为多个CSV文件,最后再将CSV文件打包成ZIP进行下载,有效解决了大数据量导出的问题。
摘要由CSDN通过智能技术生成

1.分批查数据,防止数据库内存溢出
2.生成多个csv文件
3.zip打包下载

//分批打包下载excel
    //导出说明:因为EXCEL单表只能显示104W数据,同时使用PHPEXCEL容易因为数据量太大而导致占用内存过大,
    //因此,数据的输出用csv文件的格式输出,但是csv文件用EXCEL软件读取同样会存在只能显示104W的情况,所以将数据分割保存在多个csv文件中,并且最后压缩成zip文件提供下载
    function putCsv(array $head, $data, $mark = 'attack_ip_info', $fileName = "test.csv")
    {
        set_time_limit(0);
        $sqlCount = $data->count();
        // 输出Excel文件头,可把user.csv换成你要的文件名
        header('Content-Type: application/vnd.ms-excel;charset=utf-8');
        header('Content-Disposition: attachment;filename="' . $fileName . '"');
        header('Cache-Control: max-age=0');

        $sqlLimit = 100000;//每次只从数据库取100000条以防变量缓存太大
        // 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
        $limit = 100000;
        // buffer计数器
        $cnt = 0;
        $fileNameArr = array();
        // 逐行取出数据,不浪费内存
        $disk = Storage::disk('excel_dir');
        $disk->makeDirectory(date('Y_m_d'));
        for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) {
            $fp = fopen($mark . '_' . $i . '.csv', 'w'); //生成临时文件
            //     chmod('attack_ip_info_' . $i . '.csv',777);//修改可执行权限
            $fileNameArr[] = $mark . '_' .  $i . '.csv';
            // 将数据通过fputcsv写到文件句柄
            fputcsv($fp, $head);
            $dataArr = $data->offset($i * $sqlLimit)->limit($sqlLimit)->get()->toArray();

            foreach ($dataArr as $a) {
				//有需要处理的字段可以在这里写
                $cnt++;
                if ($limit == $cnt) {
                    //刷新一下输出buffer,防止由于数据过多造成问题
                    ob_flush();
                    flush();
                    $cnt = 0;
                }
                fputcsv($fp, $a);
            }
            fclose($fp);  //每生成一个文件关闭
        }
        //进行多个文件压缩
        $zip = new \ZipArchive();
        $filename = $mark . ".zip";
        $zip->open($filename, \ZipArchive::CREATE);   //打开压缩包
        foreach ($fileNameArr as $file) {
            $zip->addFile($file, basename($file));   //向压缩包中添加文件
        }
        $zip->close();  //关闭压缩包
        foreach ($fileNameArr as $file) {
//            unlink($file); //删除csv临时文件
            Storage::delete($file);
        }
        //输出压缩文件提供下载
        header("Cache-Control: max-age=0");
        header("Content-Description: File Transfer");
        header('Content-disposition: attachment; filename=' . basename($filename)); // 文件名
        header("Content-Type: application/zip"); // zip格式的
        header("Content-Transfer-Encoding: binary"); //
        header('Content-Length: ' . filesize($filename)); //
        @readfile($filename);//输出文件;
        Storage::delete($filename);
//        unlink($filename); //删除压缩包临时文件
    }
好的,您可以使用Java中的ZipOutputStream类来实现压缩多个Excel文件。以下是一个简单的示例代码: ```java import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.support.ExcelTypeEnum; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import java.io.*; import java.util.ArrayList; import java.util.List; public class ExportExcel { public static void main(String[] args) throws IOException { // 创建多个Excel文件 List<File> fileList = createExcelFiles(); // 创建压缩包文件 File zipFile = new File("excel_files.zip"); ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(zipFile); zipOutputStream.setMethod(ZipArchiveOutputStream.DEFLATED); // 将多个Excel文件压缩到压缩包中 for (File file : fileList) { ZipArchiveEntry entry = new ZipArchiveEntry(file.getName()); entry.setSize(file.length()); zipOutputStream.putArchiveEntry(entry); FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zipOutputStream.write(buffer, 0, len); } fis.close(); zipOutputStream.closeArchiveEntry(); } // 关闭ZipOutputStream流 zipOutputStream.finish(); zipOutputStream.close(); // 删除临时Excel文件 for (File file : fileList) { file.delete(); } } private static List<File> createExcelFiles() throws FileNotFoundException { List<File> fileList = new ArrayList<>(); for (int i = 1; i <= 3; i++) { // 创建Excel文件 File file = new File("excel_" + i + ".xlsx"); OutputStream out = new FileOutputStream(file); // EasyExcel导出数据 ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX); Sheet sheet = new Sheet(1, 0); sheet.setSheetName("Sheet1"); Table table = new Table(1); List<List<String>> data = new ArrayList<>(); for (int j = 1; j <= 10; j++) { List<String> row = new ArrayList<>(); row.add("Data" + j); data.add(row); } table.setData(data); writer.write0(table, sheet); writer.finish(); // 添加Excel文件到列表中 fileList.add(file); } return fileList; } } ``` 在上面的代码中,我们首先创建了3个Excel文件,然后将它们压缩到一个名为“excel\_files.zip”的压缩包中。最后,我们删除了临时的Excel文件。注意,我们使用了Apache Commons Compress库来实现压缩操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值