IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 生成临时文件,使用document生成pdf上传到OSS -> 正文阅读

[大数据]生成临时文件,使用document生成pdf上传到OSS

// 生成临时文件
File tempFile = File.createTempFile("temp", ".pdf");
// 获取文件路径
String canonicalPath = tempFile.getCanonicalPath();
log.info("canonicalPath----->" + canonicalPath);
// pdf 输出到指定路径的文件
FileOutputStream fileOutputStream = new FileOutputStream(canonicalPath);
//建立一个书写器
PdfWriter.getInstance(document, fileOutputStream);

....

 document.close();

// 创建一个fileItem
FileItem fileItem = createFileItem(tempFile, tempFile.getName());
// 将文件转成 MultipartFile 
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
//上传文件到OSS
TempAttachVO tempAttachVO = attachUploadService.uploadAttach(multipartFile, fileItem.getName());
log.info("tempAttachVO ----> {}", tempAttachVO.getAttachPath());

这里有一个坑,一定要等document.close()之后,文件才会有数据,不然文件是有问题的

public class LadingTemplateController {

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private ContractTemplateService contractTemplateService;

    @Autowired
    private AttachUploadService attachUploadService;

    @PostMapping("foundation/template/createLadingTemplate")
    @ApiOperation("生成提货单")
    public ResultDTO workflowExportPDF(@RequestBody LadingVO ladingVO)
            throws Exception {
        ContractTemplateDTO contractTemplateDTO = new ContractTemplateDTO();
        contractTemplateDTO.setIsDefault(true);
        contractTemplateDTO.setDictCode("00040001");
        ContractTemplateVO contractTemplateVO = contractTemplateService.getByDTO(contractTemplateDTO);
        ladingVO.setWarehouseId("477ecf5b57db4ef2b23e49698dcc1422");
        WarehouseVO warehouseVO = warehouseService.get(ladingVO.getWarehouseId());


        String formatTextJson = contractTemplateVO.getFormatText();
        // 高级配置  "{\"paper\":\"0\",\"direction\":\"horizontal\",\"fontSize\":\"large\"}";
        String highSettingJson = contractTemplateVO.getHighTemplateText();

        // 高级配置对象
        JSONObject highObj = JSON.parseObject(highSettingJson);

        // 分割线
        int paper = Integer.parseInt(highObj.get("paper").toString());
        //设置分割线
        Rectangle rectangleByPaper = getRectangleByPaper(paper);

        // 横纵
        String direction = highObj.get("direction").toString();
        // 设置纸张方向
        Document document = getDocumentDirection(direction, rectangleByPaper);

        // 字体大小
        String fontSizeStr = highObj.get("fontSize").toString();
        //设置字体
        Font initFont = getFontSize(fontSizeStr);

        File tempFile = File.createTempFile("temp", ".pdf");
        String canonicalPath = tempFile.getCanonicalPath();
        log.info("canonicalPath----->" + canonicalPath);

        FileOutputStream fileOutputStream = new FileOutputStream(canonicalPath);

        //建立一个书写器
        PdfWriter.getInstance(document, fileOutputStream);

        //打开文件
        document.open();

        List<LadingDetailVO> detailList = ladingVO.getDetailList();

        JSONArray jsonArray = JSON.parseArray(formatTextJson);

        // 是否有多个提货商品
        Boolean isMuchLading = false;
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            String type = jsonObject.get("type").toString();
            if ("ladingMark".equals(type) && ladingVO.getMuchLadingDetailFlag()) {
                isMuchLading = true;
            }
        }

        Paragraph ph = new Paragraph(ladingVO.getOrgName() + "提货单", initFont);
        ph.setAlignment(Paragraph.ALIGN_CENTER);
        ph.setSpacingAfter(2);
        document.add(ph);

        Paragraph ph2 = new Paragraph("编号:" + ladingVO.getLadingCode() + "   ", initFont);
        ph2.setAlignment(Paragraph.ALIGN_RIGHT);
        ph2.setSpacingAfter(5);

        JSONObject codeObj = (JSONObject) jsonArray.get(1);

        if ("true".equals(codeObj.get("visible").toString())) {
            document.add(ph2);
        }

        Map<String, Object> ladingMap = BeanUtils.beanToMap(ladingVO);

        // 设置列宽
        int[] ints = getTableWidthList(jsonArray);

        // 商品表格列的多少
        int tableSize = 1;
        // 第一部分表格
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            String type = jsonObject.get("type").toString();
            String tableVisible = ObjectUtil.isEmpty(jsonObject.get("visible")) ? "" : jsonObject.get("visible").toString();

            if (!"table".equals(type) || !"true".equals(tableVisible)) {
                continue;
            }

            tableSize = Integer.parseInt(jsonObject.get("sizer").toString());
            JSONArray titleArray = (JSONArray) jsonObject.get("tableColumns");

            if (ObjectUtil.isEmpty(titleArray)) {
                continue;
            }
            PdfPTable table2 = getPdfPTable(tableSize);
            table2.setWidths(ints);

            List<String> titleList = new ArrayList<>();
            for (Object o : titleArray) {
                JSONObject jsonObject1 = (JSONObject) o;
                String title = jsonObject1.get("title").toString();
                String valueKey = jsonObject1.get("key").toString();
                String visible = jsonObject1.get("visible").toString();

                PdfPCell tcell = new PdfPCell(getChineseSize(title, initFont));
                setCellStyleAndColspan(tcell, 1, true);
                tcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                if ("true".equals(visible)) {
                    table2.addCell(tcell);
                    titleList.add(valueKey);
                }
            }
            Integer value = 0;
            for (int i = 0; i < detailList.size(); i++) {
                LadingDetailVO ladingDetailVO = detailList.get(i);
                Map map = BeanUtils.beanToMap(ladingDetailVO);
                for (int j = 0; j < tableSize; j++) {
                    String key = titleList.get(j);
                    String titleValue = "";
                    if (j == 0) {
                        value = value + 1;
                        titleValue = titleValue + value;
                    } else {
                        Object valueObj = map.get(key);
                        titleValue = ObjectUtil.isEmpty(valueObj) ? "" : valueObj.toString();
                    }
                    PdfPCell tcell = new PdfPCell(getChineseSize(titleValue, initFont));
                    setCellStyleAndColspan(tcell, 1, true);
                    tcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    table2.addCell(tcell);/ 
                }
            }
            document.add(table2);
        }

        List<LadingBatchNumVO> numList = ladingVO.getNumList();

        // 是否是多个提货凭证
        if (isMuchLading) {
            for (LadingBatchNumVO ladingBatchNumVO : numList) {
                Map<String, Object> subMap = BeanUtils.beanToMap(ladingBatchNumVO.getDetailList().get(0));
                List<LadingBatchDetailVO> subDetailList = ladingBatchNumVO.getDetailList();
                setLadingTable(document, jsonArray, tableSize, subMap, subDetailList, initFont);
            }
        } else {
            Map<String, Object> subMap = BeanUtils.beanToMap(ladingVO);
            List<LadingDetailVO> ladingDetailVOS = ladingVO.getDetailList();
            List<LadingBatchDetailVO> ladingBatchDetailVOS = BeanUtils.copyProperties(ladingDetailVOS, LadingBatchDetailVO.class);
            setLadingTable(document, jsonArray, tableSize, subMap, ladingBatchDetailVOS, initFont);
        }


        //最下面的仓库
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            String type = jsonObject.get("type").toString();
            String visible = ObjectUtil.isEmpty(jsonObject.get("visible")) ? "" : jsonObject.get("visible").toString();
            if (!"true".equals(visible)) {
                continue;
            }

            PdfPTable table2 = getPdfPTable(tableSize);
            // 说明
            if ("fullCell".equals(type) && ObjectUtil.isEmpty(jsonObject.get("noBorder"))) {
                String value = jsonObject.get("value").toString();
                String replace = value.replace("{br}", "\n").replace("${orgName}", ladingVO.getOrgName())
                        .replace("${customerName}", ladingVO.getCustomerName());
                PdfPCell tcell = new PdfPCell(getChineseSize(replace, initFont));
                setCellStyleAndColspan(tcell, tableSize, true);
                tcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                tcell.setHorizontalAlignment(Element.ALIGN_LEFT);
                table2.addCell(tcell);
                document.add(table2);
            }

            if (!"defaultCell".equals(type)) {
                continue;
            }

            JSONArray cellOption = null;
            JSONObject jsonObjectObj = null;
            if (ObjectUtil.isNotEmpty(jsonObject.get("cellOption"))) {
                cellOption = (JSONArray) jsonObject.get("cellOption");
                jsonObjectObj = (JSONObject) cellOption.get(0);
            }

            String valueKey = ObjectUtil.isNotEmpty(jsonObjectObj.get("valueKey")) ? jsonObjectObj.get("valueKey").toString() : "";
            String label = ObjectUtil.isNotEmpty(jsonObjectObj.get("label")) ? jsonObjectObj.get("label").toString() : "";
            String footVisible = ObjectUtil.isNotEmpty(jsonObjectObj.get("visible")) ? jsonObjectObj.get("visible").toString() : "";

            String value = ObjectUtil.isEmpty(ladingMap.get(valueKey)) ? "" : ladingMap.get(valueKey).toString();

            if ("warehouseName".equals(valueKey) && "true".equals(footVisible)) {
                setTwoRow(table2, tableSize, label, value, initFont);
            }
            if ("warehouseAddress".equals(valueKey) && "true".equals(footVisible)) {
                setTwoRow(table2, tableSize, label, warehouseVO.getAddress(), initFont);
            }
            if ("ladingMethod".equals(valueKey) && "true".equals(footVisible)) {
                if ("01".equals(value)) {
                    value = "自提";
                } else if ("02".equals(value)) {
                    value = "配送";
                } else if ("03".equals(value)) {
                    value = "过户";
                }
                setTwoRow(table2, tableSize, label, value, initFont);
            }
            if ("ladingNoticeDate".equals(valueKey) && "true".equals(footVisible)) {
                Date createDate = ladingVO.getCreateDate();
                String convert = DateUtils.convert(createDate, DateUtils.DATE_CH_FORMAT);
                setTwoRow(table2, tableSize, label, convert, initFont);
            }
            document.add(table2);
        }

        PdfPTable tableEnd = new PdfPTable(tableSize);
        tableEnd.setWidthPercentage(100); // 宽度100%填充
        tableEnd.setHorizontalAlignment(1);
        int[] columnWidths2 = new int[tableSize];
        for (int i = 0; i < tableSize; i++) {
            columnWidths2[i] = 1;
        }
        tableEnd.setWidths(columnWidths2);

        PdfPTable table3 = new PdfPTable(tableSize);
        table3.setWidthPercentage(100); // 宽度100%填充
        table3.setHorizontalAlignment(1);
        table3.setSpacingBefore(15);
        int[] columnWidths3 = new int[tableSize];
        for (int i = 0; i < tableSize; i++) {
            columnWidths3[i] = 1;
        }
        table3.setWidths(columnWidths3);

        PdfPCell tcell = new PdfPCell(getChineseSize("经办人:" + ladingVO.getCreateUserName(), initFont));
        setCellStyleAndColspan(tcell, 3, true);
        tcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        tcell.setHorizontalAlignment(Element.ALIGN_LEFT);
        tcell.setPaddingLeft(30f);
        tcell.setBorderColor(BaseColor.WHITE);
        tcell.setBackgroundColor(BaseColor.WHITE);
        table3.addCell(tcell);

        String convert = DateUtils.convert(ladingVO.getCreateDate(), DateUtils.DATE_CH_FORMAT);
        PdfPCell tcell2 = new PdfPCell(getChineseSize(ladingVO.getOrgName() + "\n" + convert + "   ", initFont));
        setCellStyleAndColspan(tcell2, tableSize - 3, true);
        tcell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
        tcell2.setHorizontalAlignment(Element.ALIGN_RIGHT);
        tcell2.setPaddingRight(30f);
        tcell2.setBorderColor(BaseColor.WHITE);
        tcell2.setBackgroundColor(BaseColor.WHITE);
        table3.addCell(tcell2);
        document.add(table3);

        document.close();

        FileItem fileItem = createFileItem(tempFile, tempFile.getName());
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);

        TempAttachVO tempAttachVO = attachUploadService.uploadAttach(multipartFile, fileItem.getName());
        log.info("tempAttachVO ----> {}", tempAttachVO.getAttachPath());


        return ResultDTO.ok();
    }

    // 设置列宽  通过前端的宽度动态设置列宽
    private int[] getTableWidthList(JSONArray jsonArray) {
        List<String> widthList = new ArrayList<>();
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            String type = jsonObject.get("type").toString();
            String tableVisible = ObjectUtil.isEmpty(jsonObject.get("visible")) ? "" : jsonObject.get("visible").toString();
            if (!"table".equals(type) || !"true".equals(tableVisible)) {
                continue;
            }
            JSONArray titleArray = (JSONArray) jsonObject.get("tableColumns");
            if (ObjectUtil.isEmpty(titleArray)) {
                continue;
            }
            for (Object o : titleArray) {
                JSONObject jsonObject1 = (JSONObject) o;
                Object visible = jsonObject1.get("visible");
                if (!"true".equals(visible.toString())) {
                    continue;
                }
                widthList.add(jsonObject1.get("width").toString());
            }
        }

        int[] ints = new int[widthList.size()];
        for (int i = 0; i < widthList.size(); i++) {
            ints[i] = Integer.parseInt(widthList.get(i));
        }
        return ints;
    }

    //设置字体大小
    private Font getFontSize(String fontSizeStr) throws DocumentException, IOException {
        int fontSize = 12;
        // 表格字体 小=12 中=13 大=14 特大=16
        //fontSize: small = 小号 middle = 中号 large = 大号 lager = 特大号
        if ("samll".equals(fontSizeStr)) {
            fontSize = 12;
        } else if ("middle".equals(fontSizeStr)) {
            fontSize = 13;
        } else if ("large".equals(fontSizeStr)) {
            fontSize = 14;
        } else if ("lager".equals(fontSizeStr)) {
            fontSize = 16;
        }

        BaseFont baseFont2 = BaseFont.createFont(new ClassPathResource("/simsun.ttf").getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font initFont = new Font(baseFont2, fontSize);
        return initFont;
    }

    //设置方向
    private Document getDocumentDirection(String direction, Rectangle a4) {
        Document document = new Document(a4);
        // 横向
        if ("horizontal".equals(direction)) {
            document = new Document(a4.rotate());
        } else {
            // 纵向
            document = new Document(a4);
        }
        return document;
    }

    设置分割线
    private Rectangle getRectangleByPaper(int paper) {
        // 如果有分割线, ury 等比例分割就行 842变成 420
        Rectangle A4 = new RectangleReadOnly(595.0F, 842.0F);
        if (paper == 1) {
            A4 = new RectangleReadOnly(595.0F, 842.0F / 2);
        } else if (paper == 2) {
            A4 = new RectangleReadOnly(595.0F, 842.0F / 3);
        } else if (paper == 3) {
            A4 = new RectangleReadOnly(595.0F, 842.0F / 4);
        } else {
            A4 = new RectangleReadOnly(595.0F, 842.0F);
        }
        return A4;
    }

    //提货商品
    private void setLadingTable(Document document, JSONArray jsonArray, int tableSize,
                                Map<String, Object> subMap, List<LadingBatchDetailVO> subDetailList,
                                Font initFont) throws Exception {
        // 提货凭证
        StringBuffer stringBuffer = new StringBuffer();
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            String type = jsonObject.get("type").toString();
            String visibleFirst = ObjectUtil.isNotEmpty(jsonObject.get("visible")) ? jsonObject.get("visible").toString() : "";
            if (!"ladingMark".equals(type) || !"true".equals(visibleFirst)) {
                continue;
            }
            JSONArray valueOption = (JSONArray) jsonObject.get("valueOption");
            for (int i = 0; i < valueOption.size(); i++) {
                JSONObject ladingObj = (JSONObject) valueOption.get(i);
                //{"visible":true,"label":"姓名","value":"${pickUpName}"}
                String visible = ladingObj.get("visible").toString();
                String label = ladingObj.get("label").toString();
                String value = ladingObj.get("value").toString();
                String replace = value.replace("{", "").replace("}", "").replace("$", "");
                if ("true".equals(visible)) {
                    String keyValue = ObjectUtil.isEmpty(subMap.get(replace)) ? "" : subMap.get(replace).toString();
                    stringBuffer.append(label + ":").append(keyValue + "  ");
                }
            }
            PdfPTable table2 = getPdfPTable(tableSize);
            setTwoRow(table2, tableSize, "提货凭证:", stringBuffer.toString(), initFont);
            document.add(table2);

            //提货商品表格大小
            int ladingSize = Integer.parseInt(jsonObject.get("sizer").toString());
            if (ladingSize == 0) {
                continue;
            }
            JSONArray titleArray = (JSONArray) jsonObject.get("tableColumns");
            if (ObjectUtil.isNotEmpty(titleArray)) {
                PdfPTable ladingTable = getPdfPTable(ladingSize + 1);

                PdfPCell tcell = new PdfPCell(getChineseSize("提货商品", initFont));
                tcell.setColspan(1);
                tcell.setRowspan(subDetailList.size() + 1);
                tcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                tcell.setHorizontalAlignment(Element.ALIGN_MIDDLE);
                ladingTable.addCell(tcell);

                List<String> subTableList = new ArrayList<>();
                for (int i = 0; i < titleArray.size(); i++) {
                    JSONObject jsonObject1 = (JSONObject) titleArray.get(i);
                    String title = jsonObject1.get("title").toString();
                    String key = jsonObject1.get("key").toString();

                    String visible = jsonObject1.get("visible").toString();
                    if ("true".equals(visible)) {
                        PdfPCell tcell2 = new PdfPCell(getChineseSize(title, initFont));
                        setCellStyleAndColspan(tcell2, 1, true);
                        tcell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
                        ladingTable.addCell(tcell2);//将该单元格添加到表格中,注意该语句必须在对该单元格设置完毕之后添加,否则在该语句之后的单元格设置将失效
                        subTableList.add(key);
                    }
                }

                for (int i = 0; i < subDetailList.size(); i++) {
                    LadingBatchDetailVO subDetailVo = subDetailList.get(i);
                    for (int j = 0; j < subTableList.size(); j++) {
                        String key = subTableList.get(j);
                        Map<String, Object> stringObjectMap = BeanUtils.beanToMap(subDetailVo);
                        String value = ObjectUtil.isEmpty(stringObjectMap.get(key)) ? "" : stringObjectMap.get(key).toString();
                        PdfPCell tcel2 = new PdfPCell(getChineseSize(value, initFont));
                        setCellStyleAndColspan(tcel2, 1, true);
                        tcel2.setVerticalAlignment(Element.ALIGN_MIDDLE);
                        ladingTable.addCell(tcel2);//将该单元格添加到表格中,注意该语句必须在对该单元格设置完毕之后添加,否则在该语句之后的单元格设置将失效
                    }
                }
                document.add(ladingTable);
            }
        }
    }

    // 一行两列
    private void setTwoRow(PdfPTable table2, int tableSize, String label, String value, Font initFont) throws Exception {
        PdfPCell tcell = new PdfPCell(getChineseSize(label, initFont));
        setCellStyleAndColspan(tcell, 2, true);
        tcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        tcell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table2.addCell(tcell);

        PdfPCell tcell2 = new PdfPCell(getChineseSize(value, initFont));
        setCellStyleAndColspan(tcell2, tableSize - 2, true);
        tcell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
        tcell2.setHorizontalAlignment(Element.ALIGN_LEFT);
        tcell2.setPaddingLeft(10f);
        table2.addCell(tcell2);
    }

    //通过列大小设置表格
    private PdfPTable getPdfPTable(int tableSize) throws DocumentException {
        PdfPTable table2 = new PdfPTable(tableSize);
        table2.setWidthPercentage(100); // 宽度100%填充
        table2.setHorizontalAlignment(1);
        int[] columnWidths2 = new int[tableSize];
        for (int i = 0; i < tableSize; i++) {
            columnWidths2[i] = 1;
        }
        table2.setWidths(columnWidths2);
        return table2;
    }

    //设置单元格样式
    private static void setCellStyleAndColspan(PdfPCell cell, int i, Boolean color) {
        cell.setColspan(i);//设置该单元格跨列 8 列
        if (color) {
//            cell.setBackgroundColor(new BaseColor(243, 243, 243)); //背景设置为灰色
            cell.setBackgroundColor(BaseColor.WHITE); //背景设置为白色
        }
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
        cell.setMinimumHeight(30L);
//        cell.setMinimumHeight(60L);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
    }

    //获取宋体大小
    private static Paragraph getChineseSize(String name, Font initFont) throws Exception {
        Paragraph ph = new Paragraph(name, initFont);
        ph.setAlignment(Paragraph.ALIGN_CENTER);
        return ph;
    }

    /*
    创建FileItem
     */
    private FileItem createFileItem(File file, String fieldName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

}

?样例展示

?

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:36:15  更:2022-03-10 22:37:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:29:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码