Java 读写Excel

  1. 简介
    最近一个朋友让我帮他处理一个excel文档,功能是从excel表中的找到第一个sheet中每个点(经纬度)在第二个地理位置中最近的3个点。给个两点的经纬度可以求出这两点之间的距离,主要是如何读写excel,幸运的是Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
    POI的主要结构:
    HSSF - 提供读写Microsoft Excel格式档案的功能。
    XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
    HWPF - 提供读写Microsoft Word格式档案的功能。
    HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
    HDGF - 提供读写Microsoft Visio格式档案的功能。

  2. 使用方式
    Apache POI官网上提供了详细的使用说明文档,具体接口如下图所示。
    这里写图片描述
    我们可以从QuickGuide中快速的学会如何使用POI。
    首先新建一个java工程,将POI的jar包都导入到项目里面,目录结构如下图:
    这里写图片描述

因为功能比较简单,我也就没有划分为多个java文件,下面是主要的功能Test类,实现了从Excel不同的sheet中读取数据并将数据写会Excel中

package sxd.learn.java;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.ss.usermodel.WorkbookFactory;

public class Test {

    public static void main(String[] args) {
        new Test().run(args[0]);
    }

    public void run(String filePath) {
        Workbook wb = null;
        try {
            InputStream inp = new FileInputStream(filePath);
            wb = WorkbookFactory.create(inp);
        } catch (EncryptedDocumentException e) {
            e.printStackTrace();
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到!");
            e.printStackTrace();
            System.exit(1);
        } catch (IOException e) {
            e.printStackTrace();
        }

        List<BSPoint> listSheet2 = readBSPointFromSheet2(wb);

        Sheet sheet1 = wb.getSheetAt(0);
        int NUM = sheet1.getLastRowNum();
        float progress = 0.0f;
        for (int rowNum = 1; rowNum <= NUM; rowNum++) {
            Row row = sheet1.getRow(rowNum);
            double lon1 = row.getCell(2).getNumericCellValue();
            double lat1 = row.getCell(3).getNumericCellValue();
            List<Dis> disList = new ArrayList<Dis>();
            for (BSPoint point : listSheet2) {
                double lon2 = point.getLon();
                double lat2 = point.getLat();
                double dis = Utils.Distance(lon1, lat1, lon2, lat2);
                if(dis != 0)
                    disList.add(new Dis(dis,
                        point.getName()));
                Collections.sort(disList); //排序
            }

            /**
             * 计算出的数据写入到该行的指定位置(没有实际写到文件中)
             */
            writeExcel(row, disList);
            progress = (float)(rowNum*1.0 / NUM) * 100;
//          Utils.updateProgress(String.valueOf(progress).length());
            Utils.showProgress(progress);
//          System.out.printf("第%d列,%.2f已经处理完成...", rowNum + 1, (rowNum*1.0 / NUM) * 100);
        }
        /*
         * 写到文件中
         * 只有关闭输出流,才能将更改写入到Excel中
         */
        try {
            FileOutputStream fileOut = new FileOutputStream(filePath);
            wb.write(fileOut);
            fileOut.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * 从sheet2中取出所有的4G基站的位置数据
     */
    public List<BSPoint> readBSPointFromSheet2(Workbook wb) {
        List<BSPoint> list = new ArrayList<BSPoint>();
        Sheet sheet2 = wb.getSheetAt(1);
        for (int rowNum = 1; rowNum <= sheet2.getLastRowNum(); rowNum++) {
            Row row = sheet2.getRow(rowNum);
            list.add(new BSPoint(rowNum, row.getCell(1).getStringCellValue(),
                    row.getCell(2).getNumericCellValue(), row.getCell(3)
                            .getNumericCellValue()));
        }
        return list;
    }

    public void writeExcel(Row row, List<Dis> disList) {
        Cell cellDis = row.getCell(4);
        Cell cellName = row.getCell(5);
        if (cellDis == null) {
            cellDis = row.createCell(4);
            cellName = row.createCell(5);
        }
        cellDis.setCellType(Cell.CELL_TYPE_NUMERIC);
        cellName.setCellType(Cell.CELL_TYPE_STRING);
        cellDis.setCellValue(disList.get(0).getDis());
        cellName.setCellValue(disList.get(0).getName());

        cellDis = row.getCell(6);
        cellName = row.getCell(7);
        if (cellDis == null){
            cellDis = row.createCell(6);
            cellName = row.createCell(7);
        }
        cellDis.setCellType(Cell.CELL_TYPE_NUMERIC);
        cellName.setCellType(Cell.CELL_TYPE_STRING);
        cellDis.setCellValue(disList.get(1).getDis());
        cellName.setCellValue(disList.get(1).getName());

        cellDis = row.getCell(8);
        cellName = row.getCell(9);
        if (cellDis == null){
            cellDis = row.createCell(8);
            cellName = row.createCell(9);
        }
        cellDis.setCellType(Cell.CELL_TYPE_NUMERIC);
        cellName.setCellType(Cell.CELL_TYPE_STRING);
        cellDis.setCellValue(disList.get(2).getDis());
        cellName.setCellValue(disList.get(2).getName());
    }

    class BSPoint {
        private Integer id; // 行
        private double lon; // 经度
        private double lat; // 纬度
        private String name; // 基站名

        public BSPoint(Integer id, String name, double lon, double lat) {
            this.id = id;
            this.name = name;
            this.lon = lon;
            this.lat = lat;
        }

        public Integer getId() {
            return id;
        }

        public double getLon() {
            return lon;
        }

        public double getLat() {
            return lat;
        }

        public String getName() {
            return name;
        }
    }

    class Dis implements Comparable<Dis> {
        private double dis;
        private String name;

        public Dis(double dis, String name) {
            this.dis = dis;
            this.name = name;
        }

        public double getDis() {
            return dis;
        }

        public String getName() {
            return name;
        }

        @Override
        public int compareTo(Dis o) {
            // TODO Auto-generated method stub
            return this.dis > o.dis ? 1 : -1;
        }
    }

}

值得注意的是Excel的写入完成是在关闭输出流后!!!
下面的是Utils类,计算两个经纬度之间的距离。

package sxd.learn.java;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class Utils {
    /**
     * 计算地球上任意两点(经纬度)距离
     * 
     * @param long1
     *            第一点经度
     * @param lat1
     *            第一点纬度
     * @param long2
     *            第二点经度
     * @param lat2
     *            第二点纬度
     * @return 返回距离 单位:米
     */
    public static double Distance(double long1, double lat1, double long2,
            double lat2) {
        double a, b, R;
        R = 6378137; // 地球半径
        lat1 = lat1 * Math.PI / 180.0;
        lat2 = lat2 * Math.PI / 180.0;
        a = lat1 - lat2;
        b = (long1 - long2) * Math.PI / 180.0;
        double d;
        double sa2, sb2;
        sa2 = Math.sin(a / 2.0);
        sb2 = Math.sin(b / 2.0);
        d = 2
                * R
                * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1)
                        * Math.cos(lat2) * sb2 * sb2));
        return d;
    }

    public static void showProgress(float value) {
        System.out.printf("<<<%.2f%%>>>\n", value);
    }

    public static void updateProgress(int num) {
        for (int i = 0; i < num; i++) {
            System.out.print("\b");
        }
    }

    public static void removeDuplicate(List list) {
          HashSet h = new HashSet(list);
          list.clear();
          list.addAll(h);
    }

    public static void removeDuplicateWithOrder(List list) {
        Set set = new HashSet();
        List newList = new ArrayList();
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            Object element = iter.next();
            if (set.add(element))
                newList.add(element);
        }
        list.clear();
        list.addAll(newList);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值