栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

将 Excel 内容转换成 MySQL 的 Insert 语句

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将 Excel 内容转换成 MySQL 的 Insert 语句

简单的思路:
  1. 想要转换,必须读取 Excel 文档
  2. 读取文档后,将读取到的文本拼接成 insert 插入语句
  3. 将拼接好的插入语句,写成 SQL 文件

有了思路以后,开始选择编程语言,我认为一般类似的小工具,都用类似 C、python 等语言开发,不过,我这里用的是Java。

好了,下面开始根据上面思路的三个步骤,进行编程!!!


思路第一条的实现

首先,Java 该如何读取 excel 文件,我看网上大多数人都用了 maven 的一个工具包,综合考虑了一下,我也用了 maven 的工具包.(Java 的 IO 应该也能做到,感兴趣的可以试试!),在创建好一个 maven 项目后,引入下面的包:

    
    
      joda-time
      joda-time
      2.9.4
    
    
    
      org.apache.poi
      poi-ooxml
      4.1.2
    
    
      org.apache.poi
      poi-scratchpad
      4.1.2
    

    
    
      com.monitorjbl
      xlsx-streamer
      2.1.0
    

然后,在Java 文件中,新建一个类,用来写读取 Excel 的代码,如下:

package com.tinkers.tools;

import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

// 读取文档类
public class ReadExcel {

    // 获取文档地址,将表格读取 成一个 XSSFWorkbook 类的文件
    public XSSFWorkbook sheetsFile(String files) throws Exception {
        // 映射 excel 文件
        File file = new File(files);
        if (!file.exists()){
            throw new Exception("文件不存在!");
        }
        // 读取文件
        InputStream in = new FileInputStream(file);
        // 使用工具包 读取整个Excel
        XSSFWorkbook sheets = new XSSFWorkbook(in);
        // 关闭流
        in.close();
        return sheets;
    }

    // 读取第几个表单
    public XSSFSheet sheetsNum(XSSFWorkbook sheets, int pageNum){
        XSSFSheet sheetAt = sheets.getSheetAt(pageNum - 1);
        return sheetAt;
    }

    // 读取标题,将标题返回为一个数组
    public ArrayList getTitleList(XSSFSheet sheetAt){
        // 定义一个 list 存标题
        ArrayList strTitle = new ArrayList<>();
        // 默认第一行为标题
        XSSFRow titleRow = sheetAt.getRow(0);
        // 遍历第一行的数据,将其转成 ArrayList
        for (int i = 0; i < titleRow.getPhysicalNumberOfCells(); i++) {
            // 获取第一行 每一列的 字段
            XSSFCell cell = titleRow.getCell(i);
            // 将读取到的字段放入 list 中
            strTitle.add(cell.getStringCellValue());
        }
        return strTitle;
    }

    //读取 表格中的内容,匹配类型,并返回一个 ArrayList
    public ArrayList getContactList(ArrayList titleList, XSSFSheet sheetAt){
        // 存放所有数据
        ArrayList objects = new ArrayList<>();

        // 遍历 excel 表
        int numberOfRows = sheetAt.getPhysicalNumberOfRows(); // 获取行数
        // 遍历每一行
        for (int i = 1; i < numberOfRows; i++) {
            // 读取每一行的数据
            XSSFRow row = sheetAt.getRow(i);
            // 获取列数
            int numberOfCells = row.getPhysicalNumberOfCells();
            HashMap cellMap = new HashMap<>();
            // ArrayList list = new ArrayList<>();
            // 遍历这一行的所有数据
            for (int j = 0; j < numberOfCells; j++) {
                XSSFCell cell = row.getCell(j);
                CellType cellType = cell.getCellType();
                // 各种类型匹配
                switch (cellType){
                    case STRING: // 字符串
                        // list.add(cell.getStringCellValue());
                        cellMap.put(titleList.get(j),cell.getStringCellValue());
                        break;
                    case BOOLEAN: // 布尔
                        // list.add(cell.getBooleanCellValue());
                        cellMap.put(titleList.get(j), cell.getBooleanCellValue());
                        break;
                    case BLANK: // 空
                        break;
                    case NUMERIC: // 数字(日期、普通数据)
                        boolean isDate = DateUtil.isCellDateFormatted(cell);
                        if (isDate) { // 日期   可能无法识别
                            // objects.add(cell.getCellStyle().getDataFormatString());
                            Date date = cell.getDateCellValue();
                            String cellDate = new DateTime(date).toString("yyyy-MM-dd HH:mm:ss");
                            // list.add(cellDate);
                            cellMap.put(titleList.get(j), cellDate);
                        } else {
                            // 不是日期格式 防止数字过长
                            // list.add(cell.toString());
                            cellMap.put(titleList.get(j), cell.getNumericCellValue());
                        }
                        break;
                    case ERROR:  break;
                }
            }
            objects.add(cellMap);
        }
        return objects;
    }
}
 

说明:我把 Excel 文档中的每一行存在一个 HashMap 中,再将这些 HashMap 循环的存在一个有序的ArrayList 中,这样做的目的,是为了方便如果 Excel 表中,有某列字段是需要去数据库的其他表中查询的,那时候,我们用的方式取值会很方便;还有一个原因就是可以保存字段原有的类型,不用全都转成字符型。

思路第二条实现

将 excel 文档读取成功后,接下来的任务就是将其拼接成 inset 语句了,详细步骤请看如下代码片段:

package com.tinkers.tools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ListToSQL {

    private static final String sqlStart = "insert into " + Const.SQL_TABLE_NAME;

    // 遍历 列名 方法
    private StringBuilder titleFor(ArrayList titleList){
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < titleList.size(); i++) {
            temp.append("`" + titleList.get(i) + "`");
            if (i != (titleList.size() - 1)){
                temp.append(",");
            }
        }
        return temp;
    }
    // 取要插入的值
    public StringBuilder valueOpt(ArrayList objects, ArrayList titleStr, int[] index, String[] tables){
        int n = 0;
        // 转成 StringBuilder
        StringBuilder sql = new StringBuilder(sqlStart);
        // 拼接数据库名字
        sql.append("(" + titleFor(titleStr) + ")" + " " + "values");

        // 将值返回
        StringBuilder valueOfCell = new StringBuilder();

        // 插入的值可以直接插入
        for (int i = 0; i < objects.size(); i++) {
            // 拼接插入语句
            valueOfCell.append(sql);

            HashMap hashMap = objects.get(i);
            valueOfCell.append("(");

            for (int j = 0; j < titleStr.size(); j++) {
                Class aClass = hashMap.get(titleStr.get(j)).getClass();
                // 插入值 需要查询别的表
                if ((index[(n % index.length)] - 1) == j){
                    int temp = (n % index.length);
                    String sqlByName = "select " + Const.FIND_RESULT + " form " + tables[temp] + " " + "where" + " " + Const.BY_COLUMN + "=";
                    valueOfCell.append("(" + sqlByName + "'" + hashMap.get(titleStr.get(j)) + "'" + "),");
                    n++;
                } else {
                    if (aClass.equals(String.class)) {
                        valueOfCell.append("'" + hashMap.get(titleStr.get(j)) + "'");
                    } else {
                        valueOfCell.append(hashMap.get(titleStr.get(j)));
                    }
                    if (j != (hashMap.size() - 1)) {
                        valueOfCell.append(",");
                    }
                }
            }
            valueOfCell.append(");n");
        }
        return valueOfCell;
    }

}

说明:

为了让这个小工具更加灵活,且有一定的扩展余地。我在拼接 insert 语句时,考虑到插入语句中的某些字段,需要查找数据库中其他的表来替换值(譬如:如果在某个表中插入“分类” 时,需要到分类表中查分类 ID 然后将 ID 存入);

所以,我用了如下的方式来拼接 SQL 语句:

insert into ws_my_asset(`XXX`) values(XXXX,(select id form XXX where XX='XX'));

思路第三条实现

经过上面的两个步骤后,我们就可以得到一个很长很长的字符串了,我们可以用 Java 的 IO 流来将这个字符串写入 SQL 文件中,具体代码如下:

package com.tinkers.tools;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class WriteSQL {
    // sql 写入文档 工具类
    public static void sqlToFile(String sqlContact){
        OutputStreamWriter pw = null;
        try {
            String content = sqlContact;
            // 创建一个文档,设置编码格式
            pw = new OutputStreamWriter(new FileOutputStream(Const.MAKE_FILE),"UTF-8");
            // 写入文档
            pw.write(content);
            // 关闭流
            pw.close();
            System.out.println("successful!");

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

写好三个工具类以后,我们就可以轻松的使用这三个工具类了!!!

辅助类:常量类

    // 要读取的 Excel 地址
    public static final String FILE_PATH = "file.xlsx";
    // 数据库生成的表名(需要插入那张表)
    public static final String SQL_TABLE_NAME = "table_name";
    // 生成的文件的地址
    public static final String MAKE_FILE = "tableName.sql";
    // 读第几个工作表
    public static final int PAGE_NUMBER = 1;
    // 第几列需要查找
    public static final int[] ARR_NUMS = {4, 5};
    // 第几列需要查找对应的表
    public static final String[] OTHER_TABLES = {"ws_table03", "ws_table04"};
    // 查找的字段名 -->> 默认是用 string 字符串,查找 id
    public static final String BY_COLUMN = "name";
    public static final String FIND_RESULT = "id";

操作类:

public void optSheets() throws Exception {

        ReadExcel readExcel = new ReadExcel();
        // 读文件
        XSSFWorkbook sheets = readExcel.sheetsFile(Const.FILE_PATH);

        // 默认读第一个
        XSSFSheet rows = readExcel.sheetsNum(sheets, Const.PAGE_NUMBER);

        // 读取第一张表的得到标题
        ArrayList titleList = readExcel.getTitleList(rows);

        // 胡获取内容
        ArrayList hashMaps = readExcel.getContactList(titleList, rows);

        // 将内容转换为 sql
        ListToSQL listToSQL = new ListToSQL();
        // int[] arrNum = {4, 5, 6};
        StringBuilder stringBuilder = listToSQL.valueOpt(hashMaps, titleList, Const.ARR_NUMS, Const.OTHER_TABLES);

        // 将 sql 写入文档
        WriteSQL writeSQL = new WriteSQL();
        writeSQL.sqlToFile(stringBuilder.toString());
    }

      Java 界的新手,希望大家多多支持,关注,提意见,也希望各位大神能给我一些指教,谢谢各位看官啦!!!

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号