java实时向zip中写excel文件并通过浏览器实现下载

@RequestMapping(value = "exportFunderZip", method = RequestMethod.GET)
public void exportFunderZip(HttpServletResponse response,Integer financeId)throws Exception{
        // 设置浏览器返回的文件类型和文件名
        response.setContentType("application/ostet-stream");
        response.setHeader("Content-disposition","attachment;filename="+new String("金融数据报表.zip".getBytes("gbk"),"iso-8859-1"));
        response.setBufferSize(1024);
        // 开启zip输出流
        ZipOutputStream zos=new ZipOutputStream(response.getOutputStream());

        exportFunderInvoiceData(financeId,zos);
        exportFunderLogisticsData(financeId,zos);
        exportFunderOrderItemData(financeId,zos);
        exportFunderPurchaseData(financeId,zos);
        exportFunderSaleorderData(financeId,zos);
        exportFunderSupplierCompanyData(financeId,zos);
        // 关闭zip输出流
        zos.close();
        }

public void exportFunderInvoiceData(Integer financeId, ZipOutputStream zos) throws Exception {
        List<FunderInvoiceDataInfo> funderInvoiceDataInfos = new FinanceDataTransferServiceClient().funderInvoiceDataExport(financeId);

        Map<String, String> fieldNameMap = new LinkedHashMap<String, String>();
        fieldNameMap.put("transCode", "结算类型");
        fieldNameMap.put("clearStatus", "结算状态");
        fieldNameMap.put("amount", "金额");
        // 设置要保存到压缩包中的文件名和路径
        ZipEntry zipEntry = new ZipEntry("结算信息报表.xls");
        // 开启一个新的输出流
        zos.putNextEntry(zipEntry);
        new ExcelFileGeneratorUtils(fieldNameMap, funderInvoiceDataInfos).expordExcel(zos);
        // 关闭新的输出流
        zos.closeEntry();
        }

package com.isuwang.soa.finance.helper

import java.io.{FileInputStream, OutputStream}

import org.apache.poi.hssf.usermodel._
import org.apache.poi.hssf.util.HSSFColor
import org.apache.poi.ss.usermodel.CellType
import org.slf4j.LoggerFactory
import scala.collection.mutable._
import scala.util.control.Breaks._

/**
  * @Description: 导出报表工具对象
  * @author jiangepng
  * @date 2017/11/30 18:25
  */
object ExcelFileGeneratorUtils {
  lazy val logger = LoggerFactory.getLogger(classOf[HSSFWorkbook])
  private val SPLIT_COUNT = 50000
  private var fieldNameKeys: ListBuffer[String] = new ListBuffer()
  private var fieldNameValues: ListBuffer[String] = new ListBuffer()
  private var fieldData: List[Any] = Nil
  private var workBook: HSSFWorkbook = _

  def ExcelFileGeneratorUtils(fieldNameMap: LinkedHashMap[String, String], fieldData: List[Any], os: OutputStream): Unit = {
    splitFieldNameMapToList(fieldNameMap)
    this.fieldData = fieldData
    expordExcelByte(os)
  }

  private def splitFieldNameMapToList(fieldNameMap: Map[String, String]) {
    val keySet = fieldNameMap.keySet
    fieldNameKeys.clear()
    fieldNameValues.clear()
    for (key <- keySet) {
      this.fieldNameKeys.append(key)
      this.fieldNameValues.append(fieldNameMap.get(key).getOrElse(""))
    }
  }

  /**
    * @Description: 创建excel工作蒲
    * @author jiangepng
    * @date 2017/12/1 11:26
    * @param
    * @return HSSFWorkbook
    */
  private def createWorkbook(): HSSFWorkbook = {
    workBook = new HSSFWorkbook
    val rows = fieldData.size
    var sheetNum = 0

    if (rows % SPLIT_COUNT == 0)
      sheetNum = rows / SPLIT_COUNT
    else
      sheetNum = rows / SPLIT_COUNT + 1

    for (i <- 1 to sheetNum) {
      val sheet = workBook.createSheet("Page" + i)
      val headRow = sheet.createRow(0) //创建行,0表示第一行(本例是excel的标题)

      for (j <- 0 until fieldNameValues.size) {
        val cell = headRow.createCell(j)
        /** ************对标题添加样式begin ********************/
        //设置列的宽度/
        sheet.setColumnWidth(j, 6000)
        //创建列的样式对象
        val cellStyle = workBook.createCellStyle()
        val font = workBook.createFont()
        font.setBold(true)
        font.setColor(HSSFColor.RED.index)
        cellStyle.setFont(font)
        cell.setCellType(CellType.STRING)

        if (fieldNameValues(j) != null) {
          cell.setCellStyle(cellStyle)
          cell.setCellValue(fieldNameValues(j).toString)
        } else {
          cell.setCellValue("")
        }
      }
      //分页处理excel的数据,遍历所有的结果
      for (k <- 0 until (if (rows < SPLIT_COUNT) rows else SPLIT_COUNT)) {
        //如果数据下标超出总的记录数的时候,就退出循环
        if (((i - 1) * SPLIT_COUNT + k) >= rows)
          break()
        // 从第二行开始,第一行是excel的标题
        val row = sheet.createRow(k + 1)
        val rowData = fieldData((i - 1) * SPLIT_COUNT + k)
        // 有多少标题就有多少属性字段
        for (n <- 0 until fieldNameKeys.size) {
          val cell = row.createCell(n)
          cell.setCellType(CellType.STRING)
          val getValue: Any = dynamicGet(rowData, fieldNameKeys(n).toString)
          cell.setCellValue(if(getValue == null) ""else getValue.toString)
        }
      }

    }
    workBook
  }

  /**
    * description: 根据属性名调用Get方法
    * @param rowData      对象
    * @param propertyName 属性名
    * @return Any
    * @author jiangpeng
    * date 2017/11/30 18:25
    */
  private def dynamicGet[T](rowData: T, propertyName: String): Any = {
    try {
      val entityClass = rowData.getClass
      val field = entityClass.getDeclaredField(propertyName)
      field.setAccessible(true)
      field.get(rowData)
    } catch {
      case ex: Exception => {
        ex.printStackTrace()
      }
    }
  }

  /**
    * @Description: 将excel中的数据写到输出流中,用于文件的输出
    * @author jiangepng
    * @date 2017/12/1 11:33
    * @param os 输出流
    */
  private def expordExcel(os: OutputStream): Unit = {
    try {
      workBook = createWorkbook()
      workBook.write(os)
      os.close()
    } catch {
      case ex: Exception => {
        logger.error(ex.getMessage, ex)
      }
    }
  }

  /**
    * @Description: 将excel中的数据写到字节输出流中,用于文件的输出
    * @author jiangepng
    * @date 2017/12/13 16:54
    * @param
    * @return
  */
  private def expordExcelByte(os: OutputStream): Unit = {
    try {
      workBook = createWorkbook()
      workBook.write(os)
    } catch {
      case ex: Exception => {
        logger.error(ex.getMessage, ex)
      }
    }
  }
}


点关注,不迷路

文章每周持续更新,可以微信搜索「 十分钟学编程 」第一时间阅读和催更,如果这个文章写得还不错,觉得有点东西的话 ~求点赞👍 求关注❤️ 求分享❤️ 
各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒋老湿

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值