/** * 导出数据到excel表格 * Created by shenjianhua on 2018-12-28 */
package com.luer.comm.excel;

import java.io.FileOutputStream;import org.apache.poi.hssf.usermodel.HSSFCell;import org.apache.poi.hssf.usermodel.HSSFCellStyle;import org.apache.poi.hssf.usermodel.HSSFFont;import org.apache.poi.hssf.usermodel.HSSFRow;import org.apache.poi.hssf.usermodel.HSSFSheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.hssf.util.CellRangeAddress;import org.apache.poi.hssf.util.HSSFColor;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;

/** * 导出数据到excel表格 * Created by shenjianhua on 2018-12-28 */@RestController@RequestMapping("exportExcel")public class ExportexcelUtil {

    /*    *    * 常用组件:

    HSSFWorkbook    excel的文档对象

    HSSFSheet       excel的表单

    HSSFRow        excel的行

    HSSFCell       excel的格子单元

    HSSFFont        excel字体

    样式:

    HSSFCellStyle    cell样式    *    * */    public static void main(String [] args) throws Exception {

        //excel的表单名        String sheetName = "操作员数据表1";        //excel的标题名        String titleName = "操作员数据表2";        //提示 没啥用        String fileName = "操作员数据表3";        //int columnNumber = 3;        int columnNumber = 9;        //int[] columnWidth = { 10, 20, 30 };        //int[] columnWidth = {40,20,20,20,20,20,20,20,20};        String[][] dataList = { { "4e7a2bbe5cc24a63b214b3824596cd543","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "4e7a2bbe5cc24a63b214b38296cd543","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg" },                { "9198a9f1acf74b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf14b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf24b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf34b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf44b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf54b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf64b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf84b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acf94b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"},                { "9198a9f1acfw4b648b50eee69d312276","2018-12-27 10:34:19","2018-12-27 10:34:19","usernamedsfsdsf","passwrodsdlkjflsd","nicknamesdgfds","18896876323","1324325432.qq.com","remarkdsgfdg"}        };        String[] columnName = { "操作员id", "创造时间", "更新时间","登录账号","登录密码","昵称","手机号码","邮箱","注释" };        new ExportexcelUtil().ExportNoResponse(sheetName, titleName,                columnNumber, /*columnWidth,*/ columnName, dataList, fileName);    }    /*    * 导出数据到excel表格    * */

    /*    * String titleName: excel标题名    *    * String sheetName: excel表单名    *    * int columnNumber: excel标题名的数量    *    * String[] columnName:excel标题名成    *    * String[][] dataList: 导入的数据集合    * */

    @RequestMapping("/export")    public void ExportNoResponse( String titleName,String sheetName,                                  int columnNumber, /*int[] columnWidth,*/                                 String[] columnName, String[][] dataList,String fileName) throws Exception {        int flag = 0;        int[] columnWidth=new int[columnNumber];        for(flag=0;flag<columnNumber;flag++){            if(flag==0){                columnWidth[flag] = 40;                //System.out.println("columnWidth[i]: "+columnWidth[flag]);            }else{

                columnWidth[flag] = 30;                //System.out.println("columnWidth[i]: "+columnWidth[flag]);            }        }

        if (columnNumber == columnWidth.length&& columnWidth.length == columnName.length) {            // 第一步,创建一个webbook,对应一个Excel文件            HSSFWorkbook wb = new HSSFWorkbook();            // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet            HSSFSheet sheet = wb.createSheet(sheetName);            // sheet.setDefaultColumnWidth(15); //统一设置列宽            for (int i = 0; i < columnNumber; i++)            {                for (int j = 0; j <= i; j++)                {                    if (i == j)                    {                        sheet.setColumnWidth(i, columnWidth[j] * 256); // 单独设置每列的宽                    }                }            }            // 创建第0行 也就是标题            HSSFRow row1 = sheet.createRow((int) 0);            row1.setHeightInPoints(50);// 设备标题的高度            // 第三步创建标题的单元格样式style2以及字体样式headerFont1            HSSFCellStyle style2 = wb.createCellStyle();            style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);            style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);            style2.setFillForegroundColor(HSSFColor.LIGHT_TURQUOISE.index);            style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);            HSSFFont headerFont1 = (HSSFFont) wb.createFont(); // 创建字体样式            headerFont1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 字体加粗            headerFont1.setFontName("黑体"); // 设置字体类型            headerFont1.setFontHeightInPoints((short) 15); // 设置字体大小            style2.setFont(headerFont1); // 为标题样式设置字体样式

            HSSFCell cell1 = row1.createCell(0);// 创建标题第一列            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0,                    columnNumber - 1)); // 合并第0到第17列            cell1.setCellValue(titleName); // 设置值标题            cell1.setCellStyle(style2); // 设置标题样式

            // 创建第1行 也就是表头            HSSFRow row = sheet.createRow((int) 1);            row.setHeightInPoints(37);// 设置表头高度

            // 第四步,创建表头单元格样式 以及表头的字体样式            HSSFCellStyle style = wb.createCellStyle();            style.setWrapText(true);// 设置自动换行            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);            style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 创建一个居中格式

            style.setBottomBorderColor(HSSFColor.BLACK.index);            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);            style.setBorderRight(HSSFCellStyle.BORDER_THIN);            style.setBorderTop(HSSFCellStyle.BORDER_THIN);

            HSSFFont headerFont = (HSSFFont) wb.createFont(); // 创建字体样式            headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 字体加粗            headerFont.setFontName("黑体"); // 设置字体类型            headerFont.setFontHeightInPoints((short) 10); // 设置字体大小            style.setFont(headerFont); // 为标题样式设置字体样式

            // 第四.一步,创建表头的列            for (int i = 0; i < columnNumber; i++)            {                HSSFCell cell = row.createCell(i);                cell.setCellValue(columnName[i]);                cell.setCellStyle(style);            }

            // 第五步,创建单元格,并设置值            for (int i = 0; i < dataList.length; i++)            {                row = sheet.createRow((int) i + 2);                // 为数据内容设置特点新单元格样式1 自动换行 上下居中                HSSFCellStyle zidonghuanhang = wb.createCellStyle();                zidonghuanhang.setWrapText(true);// 设置自动换行                zidonghuanhang                        .setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 创建一个居中格式

                // 设置边框                zidonghuanhang.setBottomBorderColor(HSSFColor.BLACK.index);                zidonghuanhang.setBorderBottom(HSSFCellStyle.BORDER_THIN);                zidonghuanhang.setBorderLeft(HSSFCellStyle.BORDER_THIN);                zidonghuanhang.setBorderRight(HSSFCellStyle.BORDER_THIN);                zidonghuanhang.setBorderTop(HSSFCellStyle.BORDER_THIN);

                // 为数据内容设置特点新单元格样式2 自动换行 上下居中左右也居中                HSSFCellStyle zidonghuanhang2 = wb.createCellStyle();                zidonghuanhang2.setWrapText(true);// 设置自动换行                zidonghuanhang2                        .setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 创建一个上下居中格式                zidonghuanhang2.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中

                // 设置边框                zidonghuanhang2.setBottomBorderColor(HSSFColor.BLACK.index);                zidonghuanhang2.setBorderBottom(HSSFCellStyle.BORDER_THIN);                zidonghuanhang2.setBorderLeft(HSSFCellStyle.BORDER_THIN);                zidonghuanhang2.setBorderRight(HSSFCellStyle.BORDER_THIN);                zidonghuanhang2.setBorderTop(HSSFCellStyle.BORDER_THIN);                HSSFCell datacell = null;                for (int j = 0; j < columnNumber; j++)                {                    datacell = row.createCell(j);                    datacell.setCellValue(dataList[i][j]);                    datacell.setCellStyle(zidonghuanhang2);                }            }

            // 第六步,将文件存到指定位置            try {                FileOutputStream fout = new FileOutputStream("D:operator.xls");                wb.write(fout);                String str = "导出" + fileName + "成功!";                System.out.println(str);                fout.close();            } catch (Exception e) {                e.printStackTrace();                String str1 = "导出" + fileName + "失败!";                System.out.println(str1);            }        } else {            System.out.println("列数目长度名称三个数组长度要一致");        }

    }

}
/** * Excel 导入到mysql * Created by shenjianhua on 2018-12-28 */
package com.luer.comm.excel;

import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;

import com.luer.operator.bean.Operator;import com.luer.operator.service.OperatorService;import org.apache.log4j.Logger;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.ss.usermodel.Cell;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.xssf.usermodel.XSSFWorkbook;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;

/** * Excel 导入到mysql * Created by shenjianhua on 2019-1-3 */@RestController@RequestMapping("/importExcel")public class ImportexcelUtil {

    private static Logger logger = Logger.getLogger(ImportexcelUtil.class);    private final static String xls = "xls";    private final static String xlsx = "xlsx";

    /**     * 读入excel文件,解析后返回     *     * @param     * @throws IOException     */

    @Autowired    OperatorService operatorService;

    /*    * 读取excel数据导入数据库    * */    @ResponseBody    @RequestMapping("/readExcel")    public List<String[]> readExcel(MultipartFile file) throws Exception {        //检查文件        checkFile(file);        //获得Workbook工作薄对象        Workbook workbook = getWorkBook(file);        //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回        List<String[]> list = new ArrayList<String[]>();        if (workbook != null) {            for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {                //获得当前sheet工作表                Sheet sheet = workbook.getSheetAt(sheetNum);                if (sheet == null) {                    continue;                }                //获得当前sheet的开始行                int firstRowNum = sheet.getFirstRowNum();                //获得当前sheet的结束行                int lastRowNum = sheet.getLastRowNum();                //循环除了第一行的所有行                for (int rowNum = firstRowNum + 1; rowNum <= lastRowNum; rowNum++) {                    //获得当前行                    Row row = sheet.getRow(rowNum);                    if (row == null) {                        continue;                    }                    //获得当前行的开始列                    int firstCellNum = row.getFirstCellNum();                    //获得当前行的列数                    int lastCellNum = row.getPhysicalNumberOfCells();                    String[] cells = new String[row.getPhysicalNumberOfCells()];                    //循环当前行                    for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {                        Cell cell = row.getCell(cellNum);                        cells[cellNum] = getCellValue(cell);                    }                    list.add(cells);                }

            }            //workbook.close();        }

        /*        * 封装对象存入数据库        *         * 修改字段的遍历次数        * */        for(int k=1;k<9;k++) {            Operator operator = new Operator();            if(null != list.get(k)[0]){                operator.setId(list.get(k)[0]);            }            if(null != list.get(k)[1]){                operator.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(list.get(k)[1]));               /* String string = "2016-10-24 21:59:06";                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                System.out.println(sdf.parse(list.get(k)[1]));*/            }            if(null != list.get(k)[2]){                operator.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(list.get(k)[1]));            }            if(null != list.get(k)[3]){                operator.setUsername(list.get(3)[3]);            }            if(null != list.get(k)[4]){                operator.setPassword(list.get(k)[4]);            }            if(null != list.get(k)[5]){                operator.setNickname(list.get(k)[5]);            }            if(null != list.get(k)[6]){                operator.setPhoneNumber(list.get(k)[6]);            }            if(null != list.get(k)[7]){                operator.setEmail(list.get(k)[8]);            }            if(null != list.get(k)[8]){                operator.setRemark(list.get(k)[8]);            }            operatorService.insertOperator(operator);        }

        return list;    }

    @ResponseBody    @RequestMapping("/readExcel2")    public String[] readExcel2(MultipartFile file) throws IOException {        //检查文件        checkFile(file);        //获得Workbook工作薄对象        Workbook workbook = getWorkBook(file);        //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回        List<String[]> list = new ArrayList<String[]>();        if (workbook != null) {            for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {                //获得当前sheet工作表                Sheet sheet = workbook.getSheetAt(sheetNum);                if (sheet == null) {                    continue;                }                //获得当前sheet的开始行                int firstRowNum = sheet.getFirstRowNum();                //获得当前sheet的结束行                int lastRowNum = sheet.getLastRowNum();                //循环除了第一行的所有行                for (int rowNum = firstRowNum + 1; rowNum <= lastRowNum; rowNum++) {                    //获得当前行                    Row row = sheet.getRow(rowNum);                    if (row == null) {                        continue;                    }                    //获得当前行的开始列                    int firstCellNum = row.getFirstCellNum();                    //获得当前行的列数                    int lastCellNum = row.getPhysicalNumberOfCells();                    String[] cells = new String[row.getPhysicalNumberOfCells()];                    //循环当前行                    for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {                        Cell cell = row.getCell(cellNum);                        cells[cellNum] = getCellValue(cell);                    }                    list.add(cells);                }            }            // workbook.close();        }

        return list.get(0);    }

    public static void checkFile(MultipartFile file) throws IOException {        //判断文件是否存在        if (null == file) {            logger.error("文件不存在!");            throw new FileNotFoundException("文件不存在!");        }        //获得文件名        String fileName = file.getOriginalFilename();        //判断文件是否是excel文件        if (!fileName.endsWith(xls) && !fileName.endsWith(xlsx)) {            logger.error(fileName + "不是excel文件");            throw new IOException(fileName + "不是excel文件");        }    }

    public static Workbook getWorkBook(MultipartFile file) {        //获得文件名        String fileName = file.getOriginalFilename();        //创建Workbook工作薄对象,表示整个excel        Workbook workbook = null;        try {            //获取excel文件的io流            InputStream is = file.getInputStream();            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象            if (fileName.endsWith(xls)) {                //2003                workbook = new HSSFWorkbook(is);            } else if (fileName.endsWith(xlsx)) {                //2007 及2007以上                workbook = new XSSFWorkbook(is);            }        } catch (IOException e) {            logger.info(e.getMessage());        }        return workbook;    }

    public static String getCellValue(Cell cell) {        String cellValue = "";        if (cell == null) {            return cellValue;        }        //把数字当成String来读,避免出现1读成1.0的情况        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {            cell.setCellType(Cell.CELL_TYPE_STRING);        }        //判断数据的类型        switch (cell.getCellType()) {            case Cell.CELL_TYPE_NUMERIC: //数字                cellValue = String.valueOf(cell.getNumericCellValue());                break;            case Cell.CELL_TYPE_STRING: //字符串                cellValue = String.valueOf(cell.getStringCellValue());                break;            case Cell.CELL_TYPE_BOOLEAN: //Boolean                cellValue = String.valueOf(cell.getBooleanCellValue());                break;            case Cell.CELL_TYPE_FORMULA: //公式                cellValue = String.valueOf(cell.getCellFormula());                break;            case Cell.CELL_TYPE_BLANK: //空值                cellValue = "";                break;            case Cell.CELL_TYPE_ERROR: //故障                cellValue = "非法字符";                break;            default:                cellValue = "未知类型";                break;        }        return cellValue;    }}

如果帮助到你 给点鼓励 点个赞吧 谢谢亲

转载于:https://www.cnblogs.com/shenhaha520/p/10214508.html

excel表格数据导入导出相关推荐

  1. iview table数据直接导出_(excel表格数据导入导出)iView如何实现excel导入导出

    请问:ERP系统的数据怎么导出Excel和Excel的数据怎么导入ERP? 一般的方法是: 在你找那个数据页面会有数据输出选项--点击 然后到登陆ERP的第一个远程桌面,会有一个资料夹 (各公司的命名 ...

  2. 用ado把excel数据写入oracle,如何将excel表格数据导入到oracle数据库对应的表中?!oracle导出excel文件...

    如何把excel里的表导入到oracle里 使用第三方工具吧,toad之类的 一个excel表格中有多个sheet,如何将其导入oracle数据库 户和要用DBA 最简单得建用户: create us ...

  3. SQL SERVER 与ACCESS、EXCEL的数据导入导出转换

    * 说明:复制表(只复制结构,源表名:a 新表名:b)       select * into b from a where 1<>1 * 说明:拷贝表(拷贝数据,源表名:a 目标表名:b ...

  4. [导入][转]精妙的SQL和SQL SERVER 与ACCESS、EXCEL的数据导入导出转换

    * 说明:复制表(只复制结构,源表名:a 新表名:b)       select * into b from a where 1<>1 * 说明:拷贝表(拷贝数据,源表名:a 目标表名:b ...

  5. SQL SERVER 和ACCESS/excel的数据导入导出

    SQL SERVER 和ACCESS/excel的数据导入导出 常规的数据导入导出: 使用DTS向导迁移你的Access数据到SQL Server,你可以使用这些步骤: 1)在SQL SERVER企业 ...

  6. oracle数据库表excel文件位置,“如何将excel表格数据导入到oracle数据库对应的表中?“数据库文件导入excel表格数据库中...

    如何实现Excel表格自动导入到数据库 库?是什么数据库?sql?access?mysql?我以sql2008为例子 1.打开SQL Server Management Studio-任务-数据 2. ...

  7. 用Matlab将Excel表格数据导入并绘制曲线

    用Matlab将Excel表格数据导入并绘制曲线 一般流程 常见问题 一般流程 准备一个已有数据的Excel表格,一般格式为 xlsx 格式: 打开Matlab,点击菜单栏中的导入数据,选择准备好的E ...

  8. python导入excel表格-Python 将Excel表格数据导入MySQL数据库

    今天分享一个刚刚完成的Python脚本,一个实用的小技能,就是利用Python代码,将EXCEL表格数据导入到MySQL数据库中!话不多说,下面代码示例. Excel表格数据.jpg 1示例代码: i ...

  9. PL/SQL Developer将Excel表格数据导入表格

    说明,在将excel表格数据导入之前,需要创建一个对应的表. 一.打开PL/SQL Developer之后,选择tools(工具)---ODBC Imoprter(ODBC导入器) 二.选择导入文件的 ...

最新文章

  1. 在ASP.NET中重写URL 方法三:在IIS7中使用HttpModule 实现无扩展名的URL重写
  2. php的session实现
  3. Mysql数据类型之浮点与二进制型数据使用案例总结
  4. 标准SQL的update语句三种用法
  5. sublimeText OmniMarkupPreviewer 404
  6. Redis工作笔记-String类型
  7. php时间序列比对,常用在线序列比对工具
  8. HDUOJ 不容易系列之(4)——考新郎
  9. tf.nn.sigmoid_cross_entropy_with_logits 分类
  10. Memcached:高性能的分布式内存缓存服务器
  11. CVPR2020-深度图超分辨率DSR新方法| Channel Attention based Iterative Residual Learning for Depth Map SR
  12. 庄子·内篇·逍遥游第一(郭象注)
  13. 【2020】win10java(jdk安装)环境变量配置和相关问题解决
  14. 微信小程序开发初体验
  15. OpenCV3的GPU模块编译
  16. 第七届万向区块链全球峰会 | 邹传伟:元宇宙经济学
  17. chrono是一个time library,C++11 std::chrono库详解
  18. 【硬见小百科】看完这篇,请不要再说不懂MOSFET!
  19. python3 采集 中国天气网 七天预报和当天生活指数
  20. 输出1~N之间所有素数

热门文章

  1. 连接GitHub提示远程主机关闭连接
  2. 又一面试题:一个猎人带着一只狼,一个女人带着两个小女孩,一个男人带着两个小男孩,他们要渡船过河。...
  3. 加拿大玩具巨头斯平玛斯特在华确权维权,爆丸专利获赔超千万,汪汪队品牌获刑事保护...
  4. Windows Snapshot Grabber 2020中文版
  5. Android 开发都有哪些好书值得一读?
  6. Java专题 Java使用第一步 环境搭建JDK及JRE(含多版本JDK切换思路)
  7. 九大遥感目标检测数据集(附下载链接)
  8. 简明扼要阐述synchronized和lock的区别
  9. 代码片段plus ??? 打工神器: 飞冰物料库
  10. 炫舞滑板机器人_教程丨自制鬼畜滑板机器人,用纸壳就能做