poi导出-多个表的多个sheet页导出

定义实体类ExcelSheet

里边写上了字段类型以及get\set方法

package com.api.ksyun.modeling.export.util;

import java.util.Arrays;
import java.util.List;

public class ExcelSheet {

    /*** sheet的名称*/
    private String fileName;

    /*** sheet里的标题*/
    private String[] handers;

    /*** sheet里的数据集*/
    private List<String[]> dataset;

    public ExcelSheet(String fileName, String[] handers, List<String[]> dataset) {
        this.fileName = fileName;
        this.handers = handers;
        this.dataset = dataset;
    }

    public String getFileName() {
        return this.fileName;
    }

    public String[] getHanders() {
        return this.handers;
    }

    public List<String[]> getDataset() {
        return this.dataset;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public void setHanders(String[] handers) {
        this.handers = handers;
    }

    public void setDataset(List<String[]> dataset) {
        this.dataset = dataset;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof ExcelSheet)) {
            return false;
        } else {
            ExcelSheet other = (ExcelSheet)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                label39: {
                    Object this$fileName = this.getFileName();
                    Object other$fileName = other.getFileName();
                    if (this$fileName == null) {
                        if (other$fileName == null) {
                            break label39;
                        }
                    } else if (this$fileName.equals(other$fileName)) {
                        break label39;
                    }

                    return false;
                }

                if (!Arrays.deepEquals(this.getHanders(), other.getHanders())) {
                    return false;
                } else {
                    Object this$dataset = this.getDataset();
                    Object other$dataset = other.getDataset();
                    if (this$dataset == null) {
                        if (other$dataset != null) {
                            return false;
                        }
                    } else if (!this$dataset.equals(other$dataset)) {
                        return false;
                    }

                    return true;
                }
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof ExcelSheet;
    }

    public int hashCode() {
//        int PRIME = true;
        int result = 1;
        Object $fileName = this.getFileName();
        result = result * 59 + ($fileName == null ? 43 : $fileName.hashCode());
        result = result * 59 + Arrays.deepHashCode(this.getHanders());
        Object $dataset = this.getDataset();
        result = result * 59 + ($dataset == null ? 43 : $dataset.hashCode());
        return result;
    }

    public String toString() {
        return "ExcelSheet(fileName=" + this.getFileName() + ", handers=" + Arrays.deepToString(this.getHanders()) + ", dataset=" + this.getDataset() + ")";
    }

}

第二步:

定义导出方法

package com.api.ksyun.modeling.export.util;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 *多个sheet导出
 */
public class ExportSheetUtil {

    public static void exportManySheetExcel(String fileName, List<ExcelSheet> mysheets, HttpServletResponse response) {
        //创建工作薄
        HSSFWorkbook wb = new HSSFWorkbook();
        //表头样式
        HSSFCellStyle style = wb.createCellStyle();
        // 设置字体
        HSSFFont font = wb.createFont();
        //设置字体名字
        font.setFontName("Courier New");
        font.setBold(true); //列 字体加粗
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置底边框;
        style.setBorderBottom(BorderStyle.THIN);
        //设置底边框颜色;
        style.setBottomBorderColor(IndexedColors.BLACK.index);
        //设置左边框;
        style.setBorderLeft(BorderStyle.THIN);
        //设置左边框颜色;
        style.setLeftBorderColor(IndexedColors.BLACK.index);
        //设置右边框;
        style.setBorderRight(BorderStyle.THIN);
        //设置右边框颜色;
        style.setRightBorderColor(IndexedColors.BLACK.index);
        //设置顶边框;
        style.setBorderTop(BorderStyle.THIN);
        //设置顶边框颜色;
        style.setTopBorderColor(IndexedColors.BLACK.index);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(HorizontalAlignment.CENTER);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        for (ExcelSheet excel : mysheets) {
            //新建一个sheet
            //获取该sheet名称
            HSSFSheet sheet = wb.createSheet(excel.getFileName());
            //获取sheet的标题名
            String[] handers = excel.getHanders();
            //第一个sheet的第一行为标题
            HSSFRow rowFirst = sheet.createRow(0);
            //写标题
            for (int i = 0; i < handers.length; i++) {
                //获取第一行的每个单元格
                HSSFCell cell = rowFirst.createCell(i);
                //往单元格里写数据
                cell.setCellValue(handers[i]);
                //加样式
                cell.setCellStyle(style);
                //设置每列的列宽
                sheet.setColumnWidth(i, 4000);
            }
            //写数据集
            List<String[]> dataset = excel.getDataset();
            for (int i = 0; i < dataset.size(); i++) {
                //获取该对象
                String[] data = dataset.get(i);
                //创建数据行
                HSSFRow row = sheet.createRow(i + 1);
                for (int j = 0; j < data.length; j++) {
                    //设置对应单元格的值
                    row.createCell(j).setCellValue(data[j]);
                }
            }
        }

        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel;charset=ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            wb.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                wb.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

第三部:

拉取数据、以及组合数据,调用导出方法进行导出

package com.api.ksyun.modeling.export.web;

import com.alibaba.fastjson.JSONObject;
import com.api.ksyun.modeling.export.util.ExcelSheet;
import com.api.ksyun.modeling.export.util.ExportSheetUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.weaver.general.TimeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.docs.docs.DocComInfo;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.integration.logging.Logger;
import weaver.integration.logging.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 离职历史员工信息导出
 */
@Path("/export/ExprotExcel")
public class ExprotUserHistoryData {

    private Logger log = LoggerFactory.getLogger();

    private static final String EXPORT_NAME = "员工离职历史信息";  //文件名称
    private static final List<String[]> SHEET_HEADS = Arrays.asList(
            new String[]{"工号", "姓名", "员工账号", "员工类型", "离职前部门", "离职前职位", "是否在试用期内", "离职日期", "离职类型", "是否可惜离职", "是否支付补偿金", "离职原因(HRBP)", "详细离职原因(HRBP)", "直接上级", "入职日期", "公司邮箱", "城市", "职级", "序列", "招聘渠道", "聘用方式", "是否二次入职", "法人公司", "项目归属", "性别", "出生日期", "年龄", "证件类型", "证件号", "首次参加工作日期", "社会工龄(年)", "司龄(年)", "最高学历", "学校名称(最高学历)", "专业", "个人邮箱", "手机", "民族", "政治面貌", "婚姻状况", "现住址", "户籍性质", "户籍所在地", "员工状态", "备注"}, //基本信息
            new String[]{"工号", "姓名", "开始日期", "结束日期", "学校名称", "学历", "专业", "附件"}, // 教育信息
            new String[]{"工号", "姓名", "开始时间", "结束时间", "公司名称", "部门", "职位", "工作职责", "工作成就"}, // 工作经历
            new String[]{"工号", "姓名", "联系人", "联系电话"}, // 紧急联系人
            new String[]{"工号", "员工姓名", "家庭关系", "成员姓名", "工作单位", "联系电话"}, // 家庭信息
            new String[]{"工号", "姓名", "调动前部门", "调动前岗位", "调动后部门", "调动后岗位", "调动生效日期"} // 调动信息
    );
    private static final List<String> SHEET_TITLES = Arrays.asList("员工基本信息", "员工教育经历", "员工工作经验", "员工紧急联系人", "员工家庭信息", "员工调动信息"); //sheet标题


    @GET
    @Path("/userHistoryData")
    public String exportModeDtData(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        RecordSet rs = new RecordSet();
        List<ExcelSheet> mysheet = new ArrayList<>();
        log.info("人员历史数据导出模块接口START");
        String status = "成功";
        String ids = Util.null2String(request.getParameter("ids"));
        try {
            //获取用户数据
            User user = HrmUserVarify.getUser(request, response);
            List<String[]> userInfoData = getUserInfo(ids, rs); //获取基本信息数据 - 如果主表没数据就不需要导出
            if (CollectionUtils.isEmpty(userInfoData)) {
                log.info("未查询到数据");
                return "未查询到数据";
            }
            // 获取工号
            List<String> workList = userInfoData
                    .stream()
                    .map(data -> data[0])
                    .collect(Collectors.toList());
            //补全数据 - ALL
            ImmutableMap<String, List<String[]>> dataMap = ImmutableMap.<String, List<String[]>>builder()
                    .put("员工基本信息", userInfoData)
                    .put("员工教育经历", getEducationInfo(workList, rs))
                    .put("员工工作经验", getWorkResumeInfo(workList, rs))
                    .put("员工紧急联系人", getContactInfo(workList, rs))
                    .put("员工家庭信息", getFamilyInfo(workList, rs))
                    .put("员工调动信息", getHrmStatusInfo(workList, rs))
                    .build();
            log.info("补全和数据" + dataMap);
            for (int i = 0; i < SHEET_TITLES.size(); i++) {
                String sheetTitle = SHEET_TITLES.get(i);
                String[] sheetHead = SHEET_HEADS.get(i);
                List<String[]> sheetData = dataMap.get(sheetTitle);
                mysheet.add(new ExcelSheet(sheetTitle, sheetHead, sheetData));
            }
            String excelName = EXPORT_NAME + "-" + Util.null2String(user.getLastname()) + "-" + TimeUtil.getCurrentDateString();
            ExportSheetUtil.exportManySheetExcel(excelName, mysheet, response);
            log.info("导出文件名称" + excelName);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("人员历史数据导出模块接口异常", e);
            status = "失败";
        }
        return status;
    }


    //员工基本信息数据
    private List<String[]> getUserInfo(String ids, RecordSet recordSet) {
        List<String[]> list = Lists.newArrayList();
        JSONObject usertypeObj = getFieldSelectObject("uf_hrm_user_info", "usertype"); //员工类型
        JSONObject isprobationObj = getFieldSelectObject("uf_hrm_user_info", "isprobation"); //是否在试用期内
        JSONObject departuretypeObj = getFieldSelectObject("uf_hrm_user_info", "departuretype"); //离职类型
        JSONObject isseverancepaidObj = getFieldSelectObject("uf_hrm_user_info", "isseverancepaid"); //是否支付补偿金
        JSONObject joblevelObj = getFieldSelectObject("uf_hrm_user_info", "joblevel"); //职级
        JSONObject hiretypeObj = getFieldSelectObject("uf_hrm_user_info", "hiretype"); //聘用方式
        JSONObject isrehiredObj = getFieldSelectObject("uf_hrm_user_info", "isrehired"); //是否2此入职
        JSONObject sexObj = getFieldSelectObject("uf_hrm_user_info", "sex"); //性别
        JSONObject cardtypeObj = getFieldSelectObject("uf_hrm_user_info", "cardtype"); //证件类型
        JSONObject educationlevelObj = getFieldSelectObject("uf_hrm_user_info", "educationlevel"); //最高学历
        JSONObject policyObj = getFieldSelectObject("uf_hrm_user_info", "policy"); //政治面貌
        JSONObject maritalstatusObj = getFieldSelectObject("uf_hrm_user_info", "maritalstatus"); //婚姻状况
        JSONObject isregrettableObj = getFieldSelectObject("uf_hrm_user_info", "isregrettable"); //是否可惜离职

        String sql = "select * from uf_hrm_user_info ";
        if (StringUtils.isNotEmpty(ids)) {
            sql += " where find_in_set(id,?)  ORDER BY workcode ";
            recordSet.executeQuery(sql, ids);
        } else {
            sql += " ORDER BY workcode ";
            recordSet.executeQuery(sql);
        }
        while (recordSet.next()) {
            String workcode = Util.null2String(recordSet.getString("workcode"));
            String username = Util.null2String(recordSet.getString("username"));
            String loginid = Util.null2String(recordSet.getString("loginid"));
            String usertype = Util.null2String(recordSet.getString("usertype"));
            usertype = usertypeObj.getString(usertype);
            String lastdepartment = Util.null2String(recordSet.getString("lastdepartment"));
            String lastposition = Util.null2String(recordSet.getString("lastposition"));
            String isprobation = Util.null2String(recordSet.getString("isprobation"));
            isprobation = isprobationObj.getString(isprobation);
            String departuredate = Util.null2String(recordSet.getString("departuredate"));
            String departuretype = Util.null2String(recordSet.getString("departuretype"));
            departuretype = departuretypeObj.getString(departuretype);
            String isregrettable = Util.null2String(recordSet.getString("isregrettable"));
            isregrettable = isregrettableObj.getString(isregrettable);
            String isseverancepaid = Util.null2String(recordSet.getString("isseverancepaid"));
            isseverancepaid = isseverancepaidObj.getString(isseverancepaid);
            String departurereason = Util.null2String(recordSet.getString("departurereason"));
            String departurereasondetail = Util.null2String(recordSet.getString("departurereasondetail"));
            String managerid = Util.null2String(recordSet.getString("managerid"));
            String startdate = Util.null2String(recordSet.getString("startdate"));
            String email = Util.null2String(recordSet.getString("email"));
            String city = Util.null2String(recordSet.getString("city"));
            String joblevel = Util.null2String(recordSet.getString("joblevel"));
            joblevel = joblevelObj.getString(joblevel);
            String sequence = Util.null2String(recordSet.getString("sequence"));
            String hiringsource = Util.null2String(recordSet.getString("hiringsource"));
            String hiretype = Util.null2String(recordSet.getString("hiretype"));
            hiretype = hiretypeObj.getString(hiretype);
            String isrehired = Util.null2String(recordSet.getString("isrehired"));
            isrehired = isrehiredObj.getString(isrehired);
            String legalcompany = Util.null2String(recordSet.getString("legalcompany"));
            String projectowner = Util.null2String(recordSet.getString("projectowner"));
            String sex = Util.null2String(recordSet.getString("sex"));
            sex = sexObj.getString(sex);
            String birthday = Util.null2String(recordSet.getString("birthday"));
            String age = Util.null2String(recordSet.getString("age"));
            String cardtype = Util.null2String(recordSet.getString("cardtype"));
            cardtype = cardtypeObj.getString(cardtype);
            String cardid = Util.null2String(recordSet.getString("cardid"));
            String workstartdate = Util.null2String(recordSet.getString("workstartdate"));
            String workmonth = Util.null2String(recordSet.getString("workmonth"));
            String tenureage = Util.null2String(recordSet.getString("tenureage"));
            String educationlevel = Util.null2String(recordSet.getString("educationlevel"));
            educationlevel = educationlevelObj.getString(educationlevel);
            String school = Util.null2String(recordSet.getString("school"));
            String major = Util.null2String(recordSet.getString("major"));
            String personalemail = Util.null2String(recordSet.getString("personalemail"));
            String mobile = Util.null2String(recordSet.getString("mobile"));
            String folk = Util.null2String(recordSet.getString("folk"));
            String policy = Util.null2String(recordSet.getString("policy"));
            policy = policyObj.getString(policy);
            String maritalstatus = Util.null2String(recordSet.getString("maritalstatus"));
            maritalstatus = maritalstatusObj.getString(maritalstatus);
            String nowaddress = Util.null2String(recordSet.getString("nowaddress")); //户籍性质
            String registered = Util.null2String(recordSet.getString("registered")); // 户籍所在地
            String registeredaddress = Util.null2String(recordSet.getString("registeredaddress"));
            String status = Util.null2String(recordSet.getString("status"));
            String bznotes = Util.null2String(recordSet.getString("bznotes"));
            String[] data = {workcode, username, loginid, usertype, lastdepartment, lastposition, isprobation, departuredate, departuretype, isregrettable, isseverancepaid, departurereason, departurereasondetail, managerid, startdate, email, city, joblevel, sequence, hiringsource, hiretype, isrehired, legalcompany, projectowner, sex, birthday, age, cardtype, cardid, workstartdate, workmonth, tenureage, educationlevel, school, major, personalemail, mobile, folk, policy, maritalstatus, nowaddress, registered, registeredaddress, status, bznotes};
            list.add(data);
        }
        return list;
    }

    //员工教育经历信息
    private List<String[]> getEducationInfo(List<String> workCodeList, RecordSet recordSet) {
        DocComInfo docComInfo = new DocComInfo();
        List<String[]> list = Lists.newArrayList();
        JSONObject educationlevelObj = getFieldSelectObject("uf_hrm_education_info", "educationlevel"); //学历
        String sql = "select * from uf_hrm_education_info where 1=1 and  find_in_set(workcode,?) ORDER BY workcode ";
        recordSet.executeQuery(sql, StringUtils.join(workCodeList, ","));
        while (recordSet.next()) {
            String workcode = Util.null2String(recordSet.getString("workcode"));
            String username = Util.null2String(recordSet.getString("username"));
            String startdate = Util.null2String(recordSet.getString("startdate"));
            String enddate = Util.null2String(recordSet.getString("enddate"));
            String school = Util.null2String(recordSet.getString("school"));
            String educationlevel = Util.null2String(recordSet.getString("educationlevel"));
            educationlevel = educationlevelObj.getString(educationlevel);
            String speciality = Util.null2String(recordSet.getString("speciality"));
            String fileAttachment = docComInfo.getMuliDocName(Util.null2String(recordSet.getString("fileAttachment")));
            fileAttachment = fileAttachment.replaceAll("<br>", ";");
            String[] data = {workcode, username, startdate, enddate, school, educationlevel, speciality, fileAttachment};
            list.add(data);
        }
        return list;
    }

    //员工工作经历信息
    private List<String[]> getWorkResumeInfo(List<String> workCodeList, RecordSet recordSet) {
        List<String[]> list = Lists.newArrayList();
        String sql = "select * from uf_hrm_workresume where 1=1 and  find_in_set(workcode,?)  ORDER BY workcode";
        recordSet.executeQuery(sql, StringUtils.join(workCodeList, ","));
        while (recordSet.next()) {
            String workcode = Util.null2String(recordSet.getString("workcode"));
            String username = Util.null2String(recordSet.getString("username"));
            String startdate = Util.null2String(recordSet.getString("startdate"));
            String enddate = Util.null2String(recordSet.getString("enddate"));
            String company = Util.null2String(recordSet.getString("company"));
            String department = Util.null2String(recordSet.getString("department"));
            String jobtitle = Util.null2String(recordSet.getString("jobtitle"));
            String workdesc = Util.null2String(recordSet.getString("workdesc"));
            String jobachievement = Util.null2String(recordSet.getString("jobAchievement"));
            String[] data = {workcode, username, startdate, enddate, company, department, jobtitle, workdesc, jobachievement};
            list.add(data);
        }
        return list;
    }


    //员工紧急联系人
    private List<String[]> getContactInfo(List<String> workCodeList, RecordSet recordSet) {
        List<String[]> list = Lists.newArrayList();
        String sql = "select * from uf_hrm_emergency_contact where 1=1 and  find_in_set(workcode,?) ORDER BY workcode ";
        recordSet.executeQuery(sql, StringUtils.join(workCodeList, ","));
        while (recordSet.next()) {
            String workcode = Util.null2String(recordSet.getString("workcode"));
            String username = Util.null2String(recordSet.getString("username"));
            String contact = Util.null2String(recordSet.getString("contact"));
            String phone = Util.null2String(recordSet.getString("phone"));
            String[] data = {workcode, username, contact, phone};
            list.add(data);
        }
        return list;
    }

    //家庭信息
    private List<String[]> getFamilyInfo(List<String> workCodeList, RecordSet recordSet) {
        List<String[]> list = Lists.newArrayList();
        JSONObject titleObj = getFieldSelectObject("uf_hrm_family_info", "title"); //家庭关系
        String sql = "select * from uf_hrm_family_info where 1=1 and  find_in_set(workcode,?) ORDER BY workcode ";
        recordSet.executeQuery(sql, StringUtils.join(workCodeList, ","));
        while (recordSet.next()) {
            String workcode = Util.null2String(recordSet.getString("workcode"));
            String username = Util.null2String(recordSet.getString("username"));
            String title = Util.null2String(recordSet.getString("title"));
            title = titleObj.getString(title);
            String membername = Util.null2String(recordSet.getString("membername"));
            String company = Util.null2String(recordSet.getString("company"));
            String telphone = Util.null2String(recordSet.getString("telphone"));
            String[] data = {workcode, username, title, membername, company, telphone};
            list.add(data);
        }
        return list;
    }


    //员工调动
    private List<String[]> getHrmStatusInfo(List<String> workCodeList, RecordSet recordSet) {
        List<String[]> list = Lists.newArrayList();
        String sql = "select * from uf_hrm_status_history where 1=1 and  find_in_set(workcode,?) ORDER BY workcode ";
        recordSet.executeQuery(sql, StringUtils.join(workCodeList, ","));
        while (recordSet.next()) {
            String workcode = Util.null2String(recordSet.getString("workcode"));
            String username = Util.null2String(recordSet.getString("username"));
            String olddepartmentid = Util.null2String(recordSet.getString("olddepartmentid"));
            String oldjobtitleid = Util.null2String(recordSet.getString("oldjobtitleid"));
            String newdepartmentid = Util.null2String(recordSet.getString("newdepartmentid"));
            String newjobtitleid = Util.null2String(recordSet.getString("newjobtitleid"));
            String changedate = Util.null2String(recordSet.getString("changedate"));
            String[] data = {workcode, username, olddepartmentid, oldjobtitleid, newdepartmentid, newjobtitleid, changedate};
            list.add(data);
        }
        return list;
    }


    /**
     * 获取下拉框值
     *
     * @param tableName
     * @param fieldName
     * @return
     */
    private JSONObject getFieldSelectObject(String tableName, String fieldName) {
        RecordSet recordSet = new RecordSet();
        JSONObject jsonObject = new JSONObject(true);
        String fieldId = "";
        String querySql = "select t1.id fieldId from workflow_billfield t1 inner join workflow_bill t2 on t1.billid=t2.id where lower(if(t1.VIEWTYPE=0,t2.TABLENAME,t1.DETAILTABLE))=? and lower(t1.FIELDNAME)=? ";
        recordSet.executeQuery(querySql, tableName.toLowerCase(), fieldName.toLowerCase());
        if (recordSet.next()) {
            fieldId = Util.null2String(recordSet.getString("fieldId"));
        }
        querySql = "SELECT SELECTVALUE,SELECTNAME from workflow_selectitem where fieldid = ? ";
        recordSet.executeQuery(querySql, fieldId);
        while (recordSet.next()) {
            String SELECTVALUE = Util.null2String(recordSet.getString("SELECTVALUE"));
            String SELECTNAME = Util.null2String(recordSet.getString("SELECTNAME"));
            jsonObject.put(SELECTVALUE, SELECTNAME);
        }
        return jsonObject;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值