【无标题】Java使用itext5 导出多个pdf 并生成zip压缩包下载

此博客展示了如何通过Java代码实现PDF导出功能,包括训练课程生成、数据处理和水印技术。它详细介绍了如何创建包含培训内容、学员信息和完成情况的定制PDF,以及生成带有公司名称和安全管理员等元素的表格。
摘要由CSDN通过智能技术生成

直接上代码:

 /**
     * 导出pdf
     *
     * @param subjCode
     */
    @GetMapping("/export_pdf")
    public void exportPdf(HttpServletResponse response, String[] subjCode) throws IOException {
        byte[] data = trainCurricuLumService.exportPdf(subjCode);
        genCode(response, data);
    }

    /**
     * 生成zip文件
     */
    private void genCode(HttpServletResponse response, byte[] data) throws IOException {
        String fileName =  DateUtil.getTimeMillis() + ".zip";
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(data, response.getOutputStream());
    }

业务逻辑处理

 @Override
    public byte[] exportPdf(String[] subjCode) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        for (String code : subjCode) {
            generatorCode(code, zip);
        }
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }

    @SneakyThrows
    private void generatorCode(String subjCode, ZipOutputStream zip) {
        TrainCurricuLum  trainCurricuLum = 根据subjCode查询数据库
        PeiXuAllVo peiXuAllVo = 根据subjCode查询数据库
        TrainRecord trainRecord = new TrainRecord(subjCode);
        List<PeiXunDaoVo> list = 根据subjCode查询数据库

        //创建Document  对象
        Document document = new Document();
        document.setPageSize(PageSize.A4);// 设置页面大小
        // 使用语言包字体
        BaseFont abf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        //换行
        //document.newPage();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, baos);
        String curricuLum = trainCurricuLum.getCurricuLum();
        if (StringUtils.isNotEmpty(trainCurricuLum.getComName())) {
            curricuLum = trainCurricuLum.getComName() + "-" + curricuLum;
        }
        //设置水印  页码
        writer.setPageEvent(new PdfPageHelper(curricuLum));
        //打开 pdf
        document.open();

        //字体
        Font font = new Font(abf, 9);
        //段落
        Paragraph p = new Paragraph(curricuLum, new Font(abf, 14, Font.BOLD));
        p.setAlignment(Paragraph.ALIGN_CENTER);
        document.add(p);
        Phrase tPhrase = new Phrase();
        tPhrase.add(Chunk.NEWLINE);// 放在容器中好用
        tPhrase.setLeading(14f);// 行间距
        document.add(tPhrase);

        //表格
        //numcolumns:列数
        PdfPTable table = new PdfPTable(12);
        //表格与上面段落的空隙
        table.setSpacingBefore(10f);
        //设置表格宽度比例为%100
        table.setWidthPercentage(100);
        // 设置表格的宽度
        table.setTotalWidth(500);
        PdfPCell cell = new PdfPCell(new Phrase("培训内容", font));
        //垂直居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        //水平居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(3);
        table.addCell(cell);

        StringBuffer str = new StringBuffer();
        trainCurricuLum.getTrainCourseWareList().forEach(trainCourseWare -> {
            if (StringUtils.isNotEmpty(str)) {
                str.append(", " + trainCourseWare.getCourseWare());
            } else {
                str.append(trainCourseWare.getCourseWare());
            }
        });

        cell = new PdfPCell(new Phrase(str.toString(), font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(9);
        table.addCell(cell);
        //公司名称
        cell = new PdfPCell(new Phrase("公司名称: " + trainCurricuLum.getComName(), font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(4);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("培训名称: " + trainCurricuLum.getCurricuLum(), font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(4);
        table.addCell(cell);
        //安全管理员
        String compereName = trainCurricuLum.getCompereName();
        if (StringUtils.isEmpty(compereName)) {
            compereName = "暂无";
        }
        cell = new PdfPCell(new Phrase("安全管理员: " + compereName, font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(4);
        table.addCell(cell);

        //第三行
        cell = new PdfPCell(new Phrase("培训要求: " + trainCurricuLum.getDuraTion() + "学时(" + (trainCurricuLum.getTotalDuration() / 60) + "分)", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(4);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("考试要求: " + (trainCurricuLum.getAssessMethod().equals("1") ? "无考核" : "考核"), font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(4);
        table.addCell(cell);
        Date learningPer = trainCurricuLum.getLearningPer();
        String strLearningPer = null;
        if (learningPer == null) {
            strLearningPer = "暂无";
        } else {
            strLearningPer = DateUtil.dateToStringDate(learningPer);

        }
        Date getLearningEnd = trainCurricuLum.getLearningEnd();
        String strLearningEnd = null;
        if (getLearningEnd == null) {
            strLearningEnd = "暂无";
        } else {
            strLearningEnd = DateUtil.dateToStringDate(getLearningEnd);
        }
        cell = new PdfPCell(new Phrase("培训截至日期: " + (strLearningPer + "至" + strLearningEnd), font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(4);
        table.addCell(cell);
        //第四行
        cell = new PdfPCell(new Phrase("总人数: " + peiXuAllVo.getZongRen() + "(人)", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(3);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("已完成: " + peiXuAllVo.getYiWan() + "(人)", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(3);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("未完成: " + peiXuAllVo.getWeiWan() + "(人)", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(3);
        table.addCell(cell);

        cell = new PdfPCell(new Phrase("完成率: " + peiXuAllVo.getSop() + "%", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(3);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("各人员完成情况", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(12);
        table.addCell(cell);

        //动态列
        cell = new PdfPCell(new Phrase("序号", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(1);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("姓名", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(2);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("身份证号", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(2);
        table.addCell(cell);

        if (trainCurricuLum.getAssessMethod().equals("1")) {
            cell = new PdfPCell(new Phrase("岗位", font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(2);
            table.addCell(cell);
        } else {
            cell = new PdfPCell(new Phrase("岗位", font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(1);
            table.addCell(cell);
        }


        cell = new PdfPCell(new Phrase("完成情况", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(2);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("完成进度", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(1);
        table.addCell(cell);
        if (trainCurricuLum.getAssessMethod().equals("2")) {
            cell = new PdfPCell(new Phrase("考核结果", font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(1);
            table.addCell(cell);
        }

        cell = new PdfPCell(new Phrase("状态", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(1);
        table.addCell(cell);
        cell = new PdfPCell(new Phrase("签名照片", font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(23f);
        cell.setColspan(1);
        table.addCell(cell);

        int size = list.size();
        for (int i = 0; i < size; i++) {
            PeiXunDaoVo peiXunDaoVo = list.get(i);
            cell = new PdfPCell(new Phrase(String.valueOf(i + 1), font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(1);
            table.addCell(cell);
            //人员习姓名
            cell = new PdfPCell(new Phrase(peiXunDaoVo.getOwnerName(), font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(2);
            table.addCell(cell);
            //身份证号
            cell = new PdfPCell(new Phrase(peiXunDaoVo.getIdCad(), font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(2);
            table.addCell(cell);
            //岗位
            if (trainCurricuLum.getAssessMethod().equals("1")) {
                cell = new PdfPCell(new Phrase("驾驶员", font));
                cell.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                cell.setFixedHeight(23f);
                cell.setColspan(2);
                table.addCell(cell);
            } else {
                cell = new PdfPCell(new Phrase("驾驶员", font));
                cell.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                cell.setFixedHeight(23f);
                cell.setColspan(1);
                table.addCell(cell);
            }

            //完成情况
            BigDecimal bigDecimal1 = new BigDecimal(peiXunDaoVo.getLengthOfStudy());
            cell = new PdfPCell(new Phrase("培训时长:" + div(bigDecimal1, new BigDecimal("60")).setScale(0, BigDecimal.ROUND_DOWN).toString() + "分", font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(2);
            table.addCell(cell);
            //已完成进度
            BigDecimal bigDecimal2 = new BigDecimal(peiXunDaoVo.getTotalDuration());
            BigDecimal bigDecimal = div(bigDecimal1, bigDecimal2).setScale(2, BigDecimal.ROUND_DOWN);
            cell = new PdfPCell(new Phrase(BigDecimalUtil.mul(bigDecimal, new BigDecimal("100")) + "%", font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(1);
            table.addCell(cell);

            if (trainCurricuLum.getAssessMethod().equals("2")) {
                String exaResults = peiXunDaoVo.getExaResults();
                if (StringUtils.isNotEmpty(exaResults)){
                    cell = new PdfPCell(new Phrase(exaResults.equals("1")?"及格":"未及格", font));
                }else{
                    cell = new PdfPCell(new Phrase("", font));
                }

                cell.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                cell.setFixedHeight(23f);
                cell.setColspan(1);
                table.addCell(cell);
            }
            //状态
            cell = new PdfPCell(new Phrase(peiXunDaoVo.getRecordState(), font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setFixedHeight(23f);
            cell.setColspan(1);
            table.addCell(cell);
            //签名照
            if (StringUtils.isNotEmpty(peiXunDaoVo.getPhoto3())) {
                Image image = loadingPicture(peiXunDaoVo.getPhoto3());
                table.addCell(image);
            } else {
                table.addCell("暂无");
            }
        }
        //重点  将数据库添加到pdf
        document.add(table);
        document.close();
        writer.close();
        String fileName = curricuLum + ".pdf";
        //fileName = URLEncoder.encode(fileName, "UTF-8");
        zip.putNextEntry(new ZipEntry(fileName));
        byte[] bytes = baos.toByteArray();
        zip.write(bytes, 0, bytes.length);
        zip.flush();
        zip.closeEntry();
    }

    /**
     * 查询图片组装image
     *
     * @param url
     * @return
     * @throws IOException
     */
    @SneakyThrows
    private Image loadingPicture(String url) throws IOException {
        byte[] imageFromURL = UrlUtil.getImageFromURL(url);
        Image image = Image.getInstance(imageFromURL);
        image.scaleAbsolute(60, 20);// 调整图片大小(宽度 高度)
        return image;
    }

将在线的图片转数组

 /**
     * 将在线url 转字节
     *
     * @param urlPath
     * @return
     */
    public static byte[] getImageFromURL(String urlPath) {
        byte[] data = null;
        InputStream is = null;
        HttpURLConnection conn = null;
        try {
            URL url = new URL(urlPath);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            // conn.setDoOutput(true);
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(6000);
            is = conn.getInputStream();
            if (conn.getResponseCode() == 200) {
                data = readInputStream(is);
            } else {
                data = null;
            }
        } catch (MalformedURLException e) {
            logger.error("MalformedURLException", e);
        } catch (IOException e) {
            logger.error("IOException", e);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                logger.error("IOException", e);
            }
            conn.disconnect();
        }
        return data;
    }


    public static byte[] readInputStream(InputStream is) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = -1;
        try {
            while ((length = is.read(buffer)) != -1) {
                baos.write(buffer, 0, length);
            }
            baos.flush();
        } catch (IOException e) {
            logger.error("IOException", e);
        }
        byte[] data = baos.toByteArray();
        try {
            is.close();
            baos.close();
        } catch (IOException e) {
            logger.error("IOException", e);
        }
        return data;
    }
}

分页水印

public class PdfPageHelper extends PdfPageEventHelper {
    private PdfTemplate tpl;
    private BaseFont bf;

    private String shuiyin;

    public PdfPageHelper(String shuiyin) {
        this.shuiyin = shuiyin;
    }

    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        tpl = writer.getDirectContent().createTemplate(100, 100);
        try {
//            bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onStartPage(PdfWriter writer, Document document) {
        super.onStartPage(writer, document);
        addTextWaterMark(writer, bf, 18, 0.1f, shuiyin);
        //addImageWaterMark(writer, 0.5f, "C:\\Users\\xxx\\Desktop\\waterMark.png");
    }

    /**
     * 重写PdfPageEventHelper中的onEndPage方法
     */
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        // 新建获得用户页面文本和图片内容位置的对象
        PdfContentByte pdfContentByte = writer.getDirectContent();
        // 保存图形状态
        pdfContentByte.saveState();
        // String text = writer.getPageNumber() + "/";
        String text = "第 " + writer.getPageNumber() + " 页";
        // 获取点字符串的宽度
        float textSize = bf.getWidthPoint(text, 9);
        pdfContentByte.beginText();
        // 设置随后的文本内容写作的字体和字号
        pdfContentByte.setFontAndSize(bf, 9);

        // 定位'X/'
        float x = (document.right() + document.left()) / 2;
        //float x = document.right();
        float y = 20f;
        pdfContentByte.setTextMatrix(x, y);
        pdfContentByte.showText(text);
        pdfContentByte.endText();

        // 将模板加入到内容(content)中- // 定位'Y'
        pdfContentByte.addTemplate(tpl, x + textSize, y);

        pdfContentByte.restoreState();
    }

/*    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        //每一次在页面写完结束后,计算一下页码,
        PdfContentByte cb = writer.getDirectContent();

        String text = "第 " + writer.getPageNumber() + " 页,共";
        float textSize = bf.getWidthPoint(text, 7);
        float textBase = document.bottom();
        cb.beginText();
        cb.setFontAndSize(bf, 8);

        cb.setTextMatrix(document.left(), textBase);
        cb.showText(text);
        cb.endText();
        cb.addTemplate(tpl, document.left() + textSize, textBase);
    }*/

    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {

//        tpl.beginText();
//        tpl.setFontAndSize(bf, 10);
//        tpl.setTextMatrix(0, 0);
//        // 设置总页数的值到模板上,并应用到每个界面
//        tpl.showText(writer.getPageNumber() + " 页");
//        tpl.endText();
       /* //文档关闭后,计算一下总页数
        tpl.beginText();
        tpl.setFontAndSize(bf, 8);
        tpl.setTextMatrix(0, 0);
        tpl.showText(writer.getPageNumber() + " 页");
        tpl.endText();*/
    }

    //文字水印
    private static void addTextWaterMark(PdfWriter pdfWriter, BaseFont bf, int fontSize, float fillOpacity, String text) {
        //添加水印
        PdfContentByte contentUnder = pdfWriter.getDirectContentUnder();
        contentUnder.beginText();
        contentUnder.setColorFill(BaseColor.BLUE);
        contentUnder.setFontAndSize(bf, fontSize);
        //设置水印透明度
        PdfGState pdfGState = new PdfGState();
        pdfGState.setFillOpacity(fillOpacity);
        contentUnder.setGState(pdfGState);

        Random random = new Random();
        for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 30; initX += 300) {
            for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 30; initY += 250) {
                contentUnder.showTextAligned(Element.ALIGN_MIDDLE, text, initX, initY, 30);
            }
        }
//        for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 30; initX += 300) {
//            for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 30; initY += 250) {
//                contentUnder.showTextAligned(Element.ALIGN_CENTER, text, initX, initY, 30);
//            }
//        }
        contentUnder.endText();
    }

    //图像水印
    private static void addImageWaterMark(PdfWriter pdfWriter, float fillOpacity, String imgUrl) {
        PdfContentByte contentUnder = pdfWriter.getDirectContentUnder();
        try {
            Image image = Image.getInstance(imgUrl);
            image.scaleToFit(200, 150);

            PdfGState pdfGState = new PdfGState();
            pdfGState.setFillOpacity(fillOpacity);
            contentUnder.setGState(pdfGState);
            Random random = new Random();

            for (float initX = random.nextInt(200) - 150; initX <= PageSize.A4.getWidth() + 40; initX += 300) {
                for (float initY = random.nextInt(200) - 150; initY <= PageSize.A4.getHeight() + 40; initY += 300) {
                    image.setAbsolutePosition(initX, initY);
                    image.setRotationDegrees(30);
                    contentUnder.addImage(image);

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值