1. 程式人生 > >poi:讀取excel檔案模板並填入資料(合併sheet)並且下載

poi:讀取excel檔案模板並填入資料(合併sheet)並且下載

今天做一個到處excel的功能,涉及到多表查詢,然後讀取excel模板檔案並寫入查詢到的資料,並且要合併sheet,合併單元格,下載等功能,附上程式碼:

Conreoller類:

/**
     * 匯出excel
     */
    public ModelAndView outContactExcel(HttpServletRequest request, HttpServletResponse response) throws Exception {
        JSONObject result = new JSONObject();
        HttpSession session = request.getSession();
        UserSession userSession = (UserSession) session.getAttribute("userSession");
        String userRole = userSession.getUserRoleNames();
        if (userRole.indexOf(CORE) < 0) {
            response.sendRedirect(AUTH);
            return null;
        }
        String projectName = af.showNull(request.getParameter("projectName"));
        String subject = af.showNull(request.getParameter("subject"));
        String keyId = af.showNull(request.getParameter("keyId"));
        String status = af.showNull(request.getParameter("status"));
        String startTime = af.showNull(request.getParameter("startTime"));
        String endTime = af.showNull(request.getParameter("endTime"));
        // 預設三個月
        if ("".equals(startTime) && "".equals(endTime)) {
            Date now = new Date();
            endTime = String.valueOf(now.getTime());
            startTime = String.valueOf(getSomeBefore(now));
        }
        // 查詢資料
        Connection conn = null;
        List<ConfirmationCountContact> list = null;
        CountService service = null;
        try {
            conn = new DBConnect().getConnect("");
            service = new CountService(conn);
            list = service.getConstactFlow(keyId, status, startTime, endTime, projectName, subject);
            if (CollectionUtils.isEmpty(list)) {
                result.put("code", Constants.FAIL_CODE);
                result.put("msg", Constants.LIST_NULL);
                return new ModelAndView(Constants.ERROR_VIEW, result);
            }
            if (list.size() > 3000) {
                result.put("code", Constants.FAIL_CODE);
                result.put("msg", Constants.NUM_MAX);
                return new ModelAndView(Constants.ERROR_VIEW, result);
            }
        } catch (Exception e) {
            result.put("code", Constants.FAIL_CODE);
            result.put("msg", Constants.SELECT_FAIL);
            return new ModelAndView(Constants.ERROR_VIEW, result);
        } finally {
            DbUtil.close(conn);
        }
        // 讀取模板檔案
        InputStream stream = ConfirmationCountAction.class.getClassLoader()
                .getResourceAsStream("template/往來函證統計表.xlsx");
        if (stream == null) {
            result.put("code", Constants.FAIL_CODE);
            result.put("msg", Constants.DOWN_FAIL);
            return new ModelAndView(Constants.ERROR_VIEW, result);
        }
        // 寫入poi
        Workbook workBook = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ServletOutputStream sout = null;
        try {
            workBook = new XSSFWorkbook(stream);
        } catch (Exception ex) {
            try {
                workBook = new HSSFWorkbook(stream);
            } catch (Exception e) {

            }
        }
        try {
            // 寫入資料
            if (workBook == null) {
                result.put("code", Constants.FAIL_CODE);
                result.put("msg", Constants.DOWN_FAIL_TWO);
                return new ModelAndView(Constants.ERROR_VIEW, result);
            }

            workBook = service.writerWorkbookContact(workBook, list);
            workBook.write(out);
            // 下載
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            String bodyName = "往來函證統計表-" + format.format(new Date()) + ".xlsx";
            sout = response.getOutputStream();
            response.reset();
            response.setContentType("application/octet-stream");
            response.addHeader("Content-Disposition",
                    "attachment;filename=" + new String(bodyName.getBytes(), "ISO-8859-1"));
            response.setHeader("Content-Length", new Integer(out.size()).toString());
            sout.write(out.toByteArray());
            sout.flush();
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code", Constants.FAIL_CODE);
            result.put("msg", Constants.DOWN_FAIL_THREE);
            return new ModelAndView(Constants.ERROR_VIEW, result);
        } finally {
            try {
                if (sout != null) {
                    sout.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public Long getSomeBefore(Date now) {
        Date before = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.add(Calendar.MONTH, -3);
        before = calendar.getTime();
        return before.getTime();
    }

Service類:

package com.zh.audit.confirmation.service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

import com.zh.audit.confirmation.until.ExcelUntil;
import com.zh.audit.confirmation.vo.ConfirmationCountContact;
import com.zh.framework.pub.db.DbUtil;
import com.zh.framework.pub.log.Log;

public class CountService {

    private Connection conn = null;

    public CountService(Connection conn) {
        this.conn = conn;
    }

    /**
     * 查詢往來函證所有相關資訊
     * 
     * @param confirmationId
     * @return
     * @throws Exception
     */
    public List<ConfirmationCountContact> getConstactFlow(String keyId, String status, String startTime, String endTime,
            String projectName, String subject) throws Exception {
        DbUtil.checkConn(conn);
        PreparedStatement ps = null;
        ResultSet rs = null;
        ConfirmationCountContact f = null;
        List<ConfirmationCountContact> list = new ArrayList<>();
        try {
            StringBuffer s = new StringBuffer();
            s.append("SELECT k.*, l.account_state,l.reply_state,l.sender_company_state,l.address_state,");
            s.append(" l.format_state,l.seal_state,l.situation_state,l.spec_explain_state,l.account,l.`explain`FROM (");
            s.append(" SELECT i.*, j.reply_time,j.reply_type,j.reply_express,j.express_num AS reply_num FROM (");
            s.append(
                    " SELECT g.*, h.confirmation_id,h.send_time,h.send_user,h.send_phone,h.send_express,h.express_num");
            s.append(
                    " FROM ( SELECT * FROM ( SELECT d.*, `subject`,e.end_time AS end_date,owes,owed,remark FROM ( SELECT * FROM (");
            s.append(" SELECT a.*, b.ProjectName AS project_name FROM ( SELECT * FROM confirmation WHERE 1 = 1");
            s.append(" AND confirmation.`status` != 99 AND type = 1  ");
            if (!"".equals(keyId)) {
                s.append(" AND key_id = '" + keyId + "' \n");
            }
            if (!"".equals(status)) {
                s.append(" AND confirmation.`status` = '" + status + "' \n");
            }
            if (!"".equals(startTime) && !"".equals(endTime)) {
                s.append(" AND create_time between '" + startTime + "' and '" + endTime + "' \n");
            }
            s.append(" ) AS a LEFT JOIN z_project AS b ON a.project_id = b.ProjectID ) AS c WHERE 1 = 1 ");
            if (!"".equals(projectName)) {
                s.append(" AND c.project_name like '%" + projectName + "%' \n");
            }
            s.append(" ) AS d LEFT JOIN confirmation_contact AS e ON e.confirmation_id = d.id ) AS f WHERE 1 = 1 ");
            if (!"".equals(subject)) {
                s.append(" AND f.`subject` = '" + subject + "' \n");
            }
            s.append(" ) AS g LEFT JOIN confirmation_send AS h ON h.confirmation_id = g.id ) AS i ");
            s.append(" LEFT JOIN confirmation_reply AS j ON j.confirmation_id = i.id ) AS k ");
            s.append(" LEFT JOIN confirmation_check AS l ON l.confirmation_id = k.id ");

            ps = conn.prepareStatement(s.toString());
            rs = ps.executeQuery();
            while (rs.next()) {
                int i = 1;
                f = new ConfirmationCountContact();
                f.setId(rs.getLong(i++));
                f.setType(rs.getInt(i++));
                f.setProjectId(rs.getLong(i++));
                f.setCustomerId(rs.getLong(i++));
                f.setKeyId(rs.getString(i++));
                f.setCompany(rs.getString(i++));
                f.setCompanyAddress(rs.getString(i++));
                f.setCompanyMobile(rs.getString(i++));
                f.setCreateUserid(rs.getString(i++));
                f.setCreateUser(rs.getString(i++));
                f.setOther(rs.getString(i++));
                f.setCreateTime(rs.getLong(i++));
                f.setUpdateTime(rs.getLong(i++));
                f.setStatus(rs.getInt(i++));
                f.setCurrency(rs.getString(i++));
                f.setSampleFeature(rs.getString(i++));
                f.setSection(rs.getString(i++));
                f.setEndTime(rs.getLong(i++));
                f.setDeposit(rs.getBigDecimal(i++));
                f.setCompanyUser(rs.getString(i++));
                f.setTwoCode(rs.getString(i++));
                f.setProjectName(rs.getString(i++));
                f.setSubject(rs.getString(i++));
                f.setEndDate(rs.getString(i++));
                f.setOwes(rs.getBigDecimal(i++));
                f.setOwed(rs.getBigDecimal(i++));
                f.setRemark(rs.getString(i++));
                f.setConfirmationId(rs.getString(i++));
                f.setSendTime(rs.getString(i++));
                f.setSendUser(rs.getString(i++));
                f.setSendPhone(rs.getString(i++));
                f.setSendExpress(rs.getString(i++));
                f.setExpressNum(rs.getString(i++));
                f.setReplyTime(rs.getString(i++));
                f.setReplyType(rs.getInt(i++));
                f.setReplyExpress(rs.getString(i++));
                f.setReplyNum(rs.getString(i++));
                f.setAccountState(rs.getInt(i++));
                f.setReplyState(rs.getInt(i++));
                f.setSenderCompanyState(rs.getInt(i++));
                f.setAddressState(rs.getInt(i++));
                f.setFormatState(rs.getInt(i++));
                f.setSealState(rs.getInt(i++));
                f.setSituationState(rs.getInt(i++));
                f.setSpecExplainState(rs.getInt(i++));
                f.setAccount(rs.getString(i++));
                f.setExplain(rs.getString(i++));
                list.add(f);
            }
        } catch (Exception e) {
            Log.error("查詢失敗", e);
            throw e;
        } finally {
            if (ps != null) {
                DbUtil.close(ps);
            }
        }
        return list;
    }

    public Workbook writerWorkbookContact(Workbook workBook, List<ConfirmationCountContact> list) {
        Sheet sheet = workBook.getSheetAt(0);
        Sheet sheet2 = workBook.getSheetAt(1);
        int size = list.size();
        for (int i = 0; i < size; i++) {
            ConfirmationCountContact c = list.get(i);
            Row row = null;
            if (i == 0) {
                row = sheet.getRow(3);
            } else {
                row = ExcelUntil.setCellStype(sheet, 3, 3 + i);
            }
            row.getCell(0).setCellValue(i + 1);
            row.getCell(1).setCellValue(c.getSampleFeature());
            row.getCell(2).setCellValue(c.getCompany());
            row.getCell(3).setCellValue(c.getSubject());
            row.getCell(4).setCellValue(String.valueOf(c.getOwes() == null ? c.getOwed() : c.getOwes()));
            row.getCell(5).setCellValue(c.getKeyId());
            if (c.getAccountState() != null) {
                if (c.getAccountState() == 1) {
                    row.getCell(6).setCellValue(String.valueOf(c.getOwes() == null ? c.getOwed() : c.getOwes()));
                    row.getCell(7).setCellValue("√");
                } else if (c.getAccountState() == 0) {
                    row.getCell(6).setCellValue(c.getAccount());
                    row.getCell(7).setCellValue("×");
                } else {
                    row.getCell(6).setCellValue("");
                    row.getCell(7).setCellValue("");
                }
            }
            row.getCell(12).setCellValue(c.getSendExpress());
            row.getCell(13).setCellValue(c.getExpressNum());
            if (c.getReplyType() != null) {
                if (c.getReplyType() == 3) {
                    row.getCell(14).setCellValue("√");
                    row.getCell(15).setCellValue("快遞");
                    row.getCell(16).setCellValue(c.getReplyState() == 1 ? "√" : "×");
                    row.getCell(17).setCellValue("");
                    row.getCell(18).setCellValue("");
                } else if (c.getReplyType() == 2) {
                    row.getCell(14).setCellValue("");
                    row.getCell(15).setCellValue("傳真");
                    row.getCell(16).setCellValue("");
                    row.getCell(17).setCellValue(c.getReplyState() == 1 ? "√" : "×");
                    row.getCell(18).setCellValue("");
                } else if (c.getReplyType() == 1) {
                    row.getCell(14).setCellValue("");
                    row.getCell(15).setCellValue("郵件");
                    row.getCell(16).setCellValue("");
                    row.getCell(17).setCellValue("");
                    row.getCell(18).setCellValue(c.getReplyState() == 1 ? "√" : "×");
                }
            }
            if (c.getSenderCompanyState() != null) {
                row.getCell(19).setCellValue(c.getSenderCompanyState() == 1 ? "√" : "×");
            }
            if (c.getAddressState() != null) {
                row.getCell(20).setCellValue(c.getAddressState() == 1 ? "√" : "×");
            }
            if (c.getFormatState() != null) {
                row.getCell(21).setCellValue(c.getFormatState() == 1 ? "√" : "×");
            }
            if (c.getSealState() != null) {
                row.getCell(22).setCellValue(c.getSealState() == 1 ? "√" : "×");
            }
            if (c.getSituationState() != null) {
                row.getCell(23).setCellValue(c.getSituationState() == 1 ? "√" : "×");
            }
            if (c.getSpecExplainState() != null) {
                if (c.getSpecExplainState() == 1) {
                    row.getCell(24).setCellValue("√");
                    row.getCell(25).setCellValue(c.getExplain());
                } else {
                    row.getCell(24).setCellValue("×");
                    row.getCell(25).setCellValue("");
                }
            }
        }
        // 複製註釋
        ExcelUntil.mergeSheet(sheet, sheet2, size + 3);
        // 刪除註釋
        workBook.removeSheetAt(1);
        // 合併單元格
        sheet.addMergedRegion(new CellRangeAddress(size + 5, size + 16, 14, 15));
        sheet.addMergedRegion(new CellRangeAddress(size + 23, size + 23, 0, 5));
        sheet.addMergedRegion(new CellRangeAddress(size + 27, size + 27, 0, 5));
        sheet.addMergedRegion(new CellRangeAddress(size + 32, size + 32, 0, 5));
        return workBook;
    }

}
excel工具類:

package com.zh.audit.confirmation.until;

import java.math.BigInteger;
import java.text.DateFormat;
import java.util.regex.Pattern;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

/**
 * excel工具類
 * 
 * @author wangjing
 *
 */
public class ExcelUntil {

    /**
     * 複製上一行的格式樣式
     * 
     * @param sheet
     * @param index
     * @param newRow
     * @return
     */
    public static Row setCellStype(Sheet sheet, int index, int newRow) {
        Row source = sheet.getRow(index);
        Row target = sheet.createRow(newRow);
        target.setHeight(source.getHeight());
        target.setRowStyle(source.getRowStyle());
        for (int i = source.getFirstCellNum(); i < source.getLastCellNum(); i++) {
            Cell scell = source.getCell(i);
            Cell cell = target.createCell(i);
            cell.setCellStyle(scell.getCellStyle());
            cell.setCellType(scell.getCellType());
        }
        return target;
    }

    /**
     * 把sheet2的內容複製到sheet1中
     * 
     * @param sheet1
     * @param sheet2
     */
    public static void mergeSheet(Sheet sheet1, Sheet sheet2, int num1) {
        if (num1 == 0) {
            num1 = sheet1.getPhysicalNumberOfRows();
        }
        int num2 = sheet2.getPhysicalNumberOfRows();
        for (int i = 0; i < num2; i++) {
            Row row2 = sheet2.getRow(i);
            Row row1 = sheet1.createRow(num1 + 1 + i);
            row1.setHeight(row2.getHeight());
            row1.setRowStyle(row2.getRowStyle());
            int first = row2.getFirstCellNum();
            int last = row2.getLastCellNum();
            for (int j = first; j < last; j++) {
                Cell cell2 = row2.getCell(j);
                Cell cell1 = row1.createCell(j);
                cell1.setCellStyle(cell2.getCellStyle());
                cell1.setCellType(cell2.getCellType());
                cell1.setCellValue(cellString(cell2, ""));
            }

        }
    }

    /**
     * 取出cell裡的值
     * 
     * @param cell
     * @param cellString
     * @return
     */
    public static String cellString(Cell cell, String cellString) {
        if (cell != null) {
            Object o = null;
            int cellType = cell.getCellType();
            switch (cellType) {
            case Cell.CELL_TYPE_BLANK:
                o = "";
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                o = cell.getBooleanCellValue();
                break;
            case Cell.CELL_TYPE_ERROR:
                o = "Bad value!";
                break;
            case Cell.CELL_TYPE_NUMERIC:
                o = getValueOfNumericCell(cell);
                break;
            case Cell.CELL_TYPE_FORMULA:
                try {
                    o = getValueOfNumericCell(cell);
                } catch (IllegalStateException e) {
                    try {
                        o = cell.getRichStringCellValue().toString();
                    } catch (IllegalStateException e2) {
                        o = cell.getErrorCellValue();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            default:
                o = cell.getRichStringCellValue().getString();
            }
            cellString = String.valueOf(o);
        }
        return cellString;
    }

    private static Object getValueOfNumericCell(Cell cell) {
        Boolean isDate = DateUtil.isCellDateFormatted(cell);
        Double d = cell.getNumericCellValue();
        Object o = null;
        if (isDate) {
            o = DateFormat.getDateInstance().format(cell.getDateCellValue());
        } else {
            o = getRealStringValueOfDouble(d);
        }
        return o;
    }

    private static String getRealStringValueOfDouble(Double d) {
        String doubleStr = d.toString();
        boolean b = doubleStr.contains("E");
        int indexOfPoint = doubleStr.indexOf('.');
        if (b) {
            int indexOfE = doubleStr.indexOf('E');
            // 小數部分
            BigInteger xs = new BigInteger(doubleStr.substring(indexOfPoint + BigInteger.ONE.intValue(), indexOfE));
            // 指數
            int pow = Integer.valueOf(doubleStr.substring(indexOfE + BigInteger.ONE.intValue()));
            int xsLen = xs.toByteArray().length;
            int scale = xsLen - pow > 0 ? xsLen - pow : 0;
            doubleStr = String.format("%." + scale + "f", d);
        } else {
            java.util.regex.Pattern p = Pattern.compile(".0$");
            java.util.regex.Matcher m = p.matcher(doubleStr);
            if (m.find()) {
                doubleStr = doubleStr.replace(".0", "");
            }
        }
        return doubleStr;
    }

}


excel 插入行操作:(上面沒用到)

插入操作其實是先把下面的行往下移,然後新建row,shiftRows就是移的方法。

eg:sheet.shiftRows(4, 10, 1, true, true);

sheet.creatRow(4);//先移位再新建行

引數解釋:4:從第幾行插入,

                  10:4-10行需要往下移,

                   1:往下移動多少行

                   後面兩個true是需要設定樣式的