Java 基于poi 读写excel文件( *.xlsx)

Java 通过poi读取excel文件需要使用XSSFWorkbook对象,需要如下依赖包

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.1.0</version>
    </dependency>

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.1.0</version>
    </dependency>

功能实现:excel列数据实现度分秒-经纬度转换。
转换公式:度分秒 --> 经纬度

(( 秒数据 ÷ 60 )+ 分数据 )÷  60 + 度数据 

现有如下数据:
在这里插入图片描述
转换成目标数据:
在这里插入图片描述

测试数据获取

度分秒N	度分秒E
31°58′58.691600″N	118°40′16.130400″E
32°58′59.008700″N	119°40′15.411700″E
33°58′59.367000″N	120°40′14.753100″E
34°58′59.734100″N	121°40′14.159800″E
35°59′00.101700″N	122°40′13.615400″E
36°59′00.469700″N	124°40′13.107800″E
37°59′00.829900″N	125°40′12.628900″E
38°59′01.198400″N	126°40′12.173600″E
39°59′01.567200″N	128°40′11.736300″E

读取EXCEL文件

读取流程从数据对象大小可分为如下:

  • XSSFWorkbook 表文件对象
  • Sheet 工作表对象 一个表文件可以包含多个工作表
  • Row 数据行对象 一个工作表含有多行数据记录
  • Cell 单元格对象 一行数据记录包含多个数据单元

创建表文件对象

  InputStream in = new FileInputStream(path);
  Workbook xwb = new XSSFWorkbook(in);

创建工作表
getSheetAt(index) 下标从0开始

// xwb.getNumberOfSheets() 统计当前表文件中包含的工作表数量
Sheet sheet = xwb.getSheetAt(0);

遍历工作表中行记录
sheet.getLastRowNum() 获得单表最大行数

 for(int numRow = 1; numRow <= sheet.getLastRowNum(); numRow++) {
	// 获取工作表的每行数据
    Row row = sheet.getRow(numRow);
 }

遍历每行中的数据单元
row.getLastCellNum() 获得最大行数据单元数量
cell.getCellType() 进行数据类型判断后获取单元格数据

 for(int numCell = 0; numCell < row.getLastCellNum(); numCell++) {
     Cell cell = row.getCell(numCell);
     // 判断单元数据类型 获取数据值 
     Object val = null; // 获取单元格的具体值
     switch(cell.getCellType()) {
       case BOOLEAN: // 布尔类型
           val = cell.getBooleanCellValue();
           break;
       case STRING: // 字符串类型
           val = cell.getStringCellValue();
           break;
       case NUMERIC: // 数值类型
           val = cell.getNumericCellValue();
           break;
       default: //其它类型
           break;
   }
 }

新建EXCEL文件并写入数据

创建表文件对象

Workbook wb = new XSSFWorkbook();

创建工作表对象
设定工作表名称

Sheet sheet = wb.createSheet("new_sheetName");

数据行数据设定
第一行数据 0 可为标题

Row titleRow = sheet.createRow(0);
//把已经写好的标题行写入excel文件中
String[] title = {"列1""列2""列3""列4"};
for (int i = 0; i < title.length; i++) {
    cell = titleRow.createCell(i);
    cell.setCellValue(title[i]);
}

从第二行开始进行数据填充

Row row = null;
for (int i = 0; i < ens.size(); i++) {// ens为需要写入的行数据集合
      //创建新行
      row = sheet.createRow(i + 1);
      //把值一一写进单元格里
      //设置第一列为自动递增的序号
      row.createCell(0).setCellValue(ens.get(i).getN_dfm());//度分秒-纬度数据
      row.createCell(1).setCellValue(ens.get(i).getE_dfm());//度分秒-经度数据
      row.createCell(2).setCellValue(ens.get(i).getN_jwd());//纬度数据
      row.createCell(3).setCellValue(ens.get(i).getE_jwd());//经度数据
  }

设置单元格自适应

for (int i = 0; i < title.length; i++) {
    sheet.autoSizeColumn(i, true);
}

数据写入文件

OutputStream fileOut = null;
try {
    //创建上传文件目录
    fileOut = new FileOutputStream(newFile);
    wb.write(fileOut);
    fileOut.close();
    wb.close();
}catch (Exception e){
    e.printStackTrace();
}

完整代码如下

EN.class 数据对象

package boke_simulation.tools;

/**
 * @ClassName EN
 * @Description TODO
 * @Author bb
 * @Date 2021/6/8 14:26
 */
public class EN {
    private String N_dfm;
    private String E_dfm;
    private String N_jwd;
    private String E_jwd;

    public EN(String n_dfm, String e_dfm, String n_jwd, String e_jwd) {
        N_dfm = n_dfm;
        E_dfm = e_dfm;
        N_jwd = n_jwd;
        E_jwd = e_jwd;
    }

    public String getN_dfm() {
        return N_dfm;
    }

    public void setN_dfm(String n_dfm) {
        N_dfm = n_dfm;
    }

    public String getE_dfm() {
        return E_dfm;
    }

    public void setE_dfm(String e_dfm) {
        E_dfm = e_dfm;
    }

    public String getN_jwd() {
        return N_jwd;
    }

    public void setN_jwd(String n_jwd) {
        N_jwd = n_jwd;
    }

    public String getE_jwd() {
        return E_jwd;
    }

    public void setE_jwd(String e_jwd) {
        E_jwd = e_jwd;
    }

    @Override
    public String toString() {
        return "EN{" +
                "N_dfm='" + N_dfm + '\'' +
                ", E_dfm='" + E_dfm + '\'' +
                ", N_jwd='" + N_jwd + '\'' +
                ", E_jwd='" + E_jwd + '\'' +
                '}';
    }
}

HandlerXLSX.class poi读写excel

package boke_simulation.tools;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @ClassName HandlerXLSX
 * @Description TODO
 * @Author bb
 * @Date 2021/5/20 9:39
 */
public class HandlerXLSX {
    // 经纬度转换
    private static ArrayList<EN> ens = new ArrayList<>();
    private static String[] title = {"度分秒N","度分秒E","纬度N","经度E"};
    private static String sheetName;
	
    public static void readXlsx(String path) {
        Workbook xwb = null;
        try{
            InputStream is = new FileInputStream(path);
            // 读取的时候可以使用流,也可以直接使用文件名
            xwb = new XSSFWorkbook(is);
                System.out.println("xlsx 文件对象:"+xwb);
            // 如有需要可以循环读取工作表sheet
			// for(int numSheet = 0; numSheet < xwb.getNumberOfSheets(); numSheet++) {}
            //  这里直接读取第一张工作表
            Sheet sheet = xwb.getSheetAt(0);   
            sheetName = sheet.getSheetName();
            System.out.println("工作表名"+sheetName);
            //  循环row,如果第一行是字段title,则 numRow = 1
            for(int numRow = 1; numRow <= sheet.getLastRowNum(); numRow++) {
                // 获取工作表的一行数据
                Row row = sheet.getRow(numRow);
                // 某行数据为空则跳过
                if(row == null) {
                    continue;
                }
                Object v = "";  //ceil值获取
                String[] s=new String[4];
                //  循环cell
                for(int numCell = 0; numCell < row.getLastCellNum(); numCell++) {
                    Cell cell = row.getCell(numCell);
                    // 某个单元格数据为空则跳过
                    if(cell == null) {
                        v = "null";
                    }else {
                        v = getValue(cell);
                    }
                    if ((v instanceof String) && (((String) v).contains("N")||(((String) v).contains("E")))){
                        //31°58′58.691600″N
                        String[] split = ((String) v).split("[°′″]");
                        Double a = (Double.parseDouble(split[2])/60+Double.parseDouble(split[1]))/60+ Double.parseDouble(split[0]);
                        // 经纬度判断实现
                        DecimalFormat df = new DecimalFormat("0.000000");
                        String value = df.format(a)+split[3];
                        if (((String) v).contains("N")){
                            s[0] = v+"";
                            s[2] = value;
                        }
                        if (((String) v).contains("E")){
                            s[1] = v+"";
                            s[3] = value;
                        }
                    }
                }
                EN en = new EN(s[0], s[1], s[2], s[3]);
                ens.add(en);
            }

        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            try{// 资源释放 poi 读取数据消耗大量内存
                if(xwb != null){
                    xwb.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return null;
    }


    // 获取每个ceil的单元数据 String Boolean Number
    public static Object getValue(Cell cell) {
        Object val = null; // 获取单元格的具体值
        switch(cell.getCellType()) {
            case BOOLEAN: // 布尔类型
                val = String.valueOf(cell.getBooleanCellValue());
                break;
            case STRING: // 字符串类型
                val = cell.getStringCellValue().trim();
                break;
            case NUMERIC: // 数值类型
                val = cell.getNumericCellValue();
                break;
            default: //其它类型
                break;
        }
        return val;
    }

    /**
     * 已有excel中新增列数据  文件名和已有excel文件名相同
     * @param filename
     */
    public static void modifyExcel(String filename){
        try {
        Workbook wb = new XSSFWorkbook(new FileInputStream(filename));
        Sheet ENSheet = wb.getSheetAt(0);
        int cellnum = ENSheet.getRow(1).getLastCellNum();

        // 标题新增列
        Row row = ENSheet.getRow(0);
        row.createCell(cellnum).setCellValue("纬度");
        row.createCell(cellnum+1).setCellValue("经度");

        for (int i = 0; i < ens.size(); i++) {
            //获取已有行数据
            row = ENSheet.getRow(i + 1);
            //把值一一写进单元格里
            //设置第一列为自动递增的序号
            row.createCell(cellnum).setCellValue(ens.get(i).getN_jwd());
            row.createCell(cellnum+1).setCellValue(ens.get(i).getE_jwd());
        }

        OutputStream fileOut = null;
        //创建上传文件目录
        fileOut = new FileOutputStream(filename);
        wb.write(fileOut);
        fileOut.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 度分秒 经纬度数据写入新表
     * @param newfilename
     */
    public static void createNewExcel(String newfilename){
        Workbook wb = new XSSFWorkbook();
        // 设定表名
        Sheet sheet = wb.createSheet(sheetName);
        Row titleRow = sheet.createRow(0);
        Cell cell = null;

        //把已经写好的标题行写入excel文件中
        for (int i = 0; i < title.length; i++) {
            cell = titleRow.createCell(i);
            cell.setCellValue(title[i]);
        }
        Row row = null;
        for (int i = 0; i < ens.size(); i++) {
            //创建list.size()行数据
            row = sheet.createRow(i + 1);
            //把值一一写进单元格里
            //设置第一列为自动递增的序号
            row.createCell(0).setCellValue(ens.get(i).getN_dfm());
            row.createCell(1).setCellValue(ens.get(i).getE_dfm());
            row.createCell(2).setCellValue(ens.get(i).getN_jwd());
            row.createCell(3).setCellValue(ens.get(i).getE_jwd());
        }

        //设置单元格宽度自适应,在此基础上把宽度调至1.5倍
        for (int i = 0; i < title.length; i++) {
            sheet.autoSizeColumn(i, true);
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 15 / 10);
        }
            OutputStream fileOut = null;
        try {
            //创建上传文件目录
            fileOut = new FileOutputStream(newfilename);
            wb.write(fileOut);
            fileOut.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        readXlsx("流程数据.xlsx");
        createNewExcel("流程数据_new.xlsx");
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java读写Excel文件(.xlsx)有多种方法,其中比较常用的是使用Apache POI库。以下是一个简单示例: 1. 导入Apache POI库 你可以在Maven项目中添加以下依赖项: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> ``` 或者下载POI库的jar并将其添加到项目中。 2. 读取Excel文件 ```java import java.io.File; import java.io.FileInputStream; import java.io.IOException; 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; public class ReadExcel { public static void main(String[] args) { try { FileInputStream file = new FileInputStream(new File("example.xlsx")); // 创建工作簿 Workbook workbook = new XSSFWorkbook(file); // 选择第一个工作表 Sheet sheet = workbook.getSheetAt(0); // 迭代行 for (Row row : sheet) { // 迭代单元格 for (Cell cell : row) { // 获取单元格的值 String cellValue = cell.getStringCellValue(); System.out.print(cellValue + "\t"); } System.out.println(); } // 关闭工作簿 workbook.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 上面的代码打开名为“example.xlsx”的Excel文件并打印出所有单元格的值。 3. 写入Excel文件 ```java import java.io.FileOutputStream; import java.io.IOException; 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; public class WriteExcel { public static void main(String[] args) { try { // 创建工作簿 Workbook workbook = new XSSFWorkbook(); // 创建工作表 Sheet sheet = workbook.createSheet("Sheet1"); // 创建行 Row row = sheet.createRow(0); // 创建单元格并设置值 Cell cell = row.createCell(0); cell.setCellValue("Hello, world!"); // 写入文件 FileOutputStream file = new FileOutputStream("example.xlsx"); workbook.write(file); // 关闭工作簿 workbook.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 上面的代码创建了一个名为“Sheet1”的工作表,并在第一行第一列写入了“Hello, world!”。最后将工作簿保存到名为“example.xlsx”的文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值