Java操作Excel表(一) 首次源码分析和初次读写操作

Excel表系列 同时被 2 个专栏收录
2 篇文章 0 订阅
7 篇文章 0 订阅

Java操作Excel表(一) 首次源码分析和初次读写操作

前言

       前段时间一直想着用Python来操作Excel表,但是发现自己由于长期使用Java,C++这种语法类型的语言后,实在是难以适应Python的语法,最后决定还是来用Java操作。在网上看到有一些jar包可以实现,于是我就去Maven网站上找了一下。导下依赖吧。

       由于我也是第一次接触这个jar包,所以今天想先看一下源码和它的功能再来研究怎么使用。如果理解错了还望指出,多多交流。^_^

       不想看源码想捡现成的可以直接翻到最下面^_^

       看源码最快也最直接的方式就是把注释和方法名称,变量名称翻译了。英语不好的同学最好建议下载一个有道词典

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6.12</version>
        </dependency>

Workbook类

       英文意思是(计算机上面的工作簿)。这个类表示工作簿。包含各种工厂方法并提供提供对工作表访问的各种访问器。

public abstract class Workbook
{
  /**
   * 软件的当前版本
   */
  private static final String VERSION = "2.6.12";
  /**
   * 构造函数
   */
  protected Workbook() { }

  /**
   * 获取此工作簿中的工作表。使用此方法为大型工作表可能导致性能问题。
   * @return 返回单个表的数组
   */
  public abstract Sheet[] getSheets();

  /**
   * 获取表单名称
   * @return 包含工作表名称的字符串数组
   */
  public abstract String[] getSheetNames();

  /**
		获取此工作簿中的指定工作表如随附的技术说明所述,每次通话
		getSheet强制重新读取工作表(出于内存原因)。因此,不要对这个方法进行不必要的调用。此外,
		在客户端代码中不保留对Sheets的不必要的引用,如这将阻止垃圾回收器释放内存
		 @param index reQuired表的零索引
		@return索引指定的工作表
   */
  public abstract Sheet getSheet(int index)
    throws IndexOutOfBoundsException;

  /**
	从工作簿中获取具有指定名称的工作表。如随附的技术说明所述,每次通话
	getSheet强制重新读取工作表(出于内存原因)。因此,不要对这个方法进行不必要的调用。此外,
	在客户端代码中不保留对Sheets的不必要的引用,如这将阻止垃圾回收器释放内存
	 @param name表名
	@return指定名称的工作表,如果没有找到则为空
   */
  public abstract Sheet getSheet(String name);

  /**
   * 软件版本的访问器
   * @return the version
   */
  public static String getVersion()
  {
    return VERSION;
  }

  /**
   * 返回此工作簿中的工作表数目
   * @return 此工作簿中的工作表数目
   */
  public abstract int getNumberOfSheets();

  /**
		从工作簿获取命名单元格。如果这个名字指的是范围的单元格,则返回左上角的单元格。如果
	  无法找到名称,返回null。
		这是一个方便的函数,可以快速访问内容的单细胞。如果您需要进一步的信息(如
		工作表或范围内相邻的单元格)使用功能更丰富的方法,findByName,它返回一个范围列表
		@param name要搜索的单元格名称/范围
   */
  public abstract Cell findCellByName(String name);

  /**
		返回指定位置的单元格。“Sheet1 ! A4”。这与使用CellReferenceHelper与它的
		相关的性能开销,因此它应该要节约使用
		@param loc要检索的单元格
		@return指定位置的单元格
   */
  public abstract Cell getCell(String loc);

  /**
		从该工作簿获取指定的范围。Range对象返回
		包含从左上到右下的所有单元格
		范围的*。
	  如果指定的范围包含相邻的范围,
	 Range[]将包含一个对象;对不相邻的范围时,必须返回长度大于1的数组。
		*如果指定范围包含单个单元格,则左上角和
		*右下角的单元格将是相同的单元格
		* @param name要搜索的单元格名称/范围
		* @返回单元格的范围,如果范围不存在则为NULL
   */
  public abstract Range[] findByName(String name);

  /**
   * 获取命名范围
   * @return 返回工作簿中命名单元格的列表
   */
  public abstract String[] getRangeNames();


  /**
   * 确定工作表是否受保护
   * @return TRUE 如果工作簿受到保护,则为FALSE
   */
  public abstract boolean isProtected();

  /**
			*解析excel文件。
	*如果工作簿是密码保护的,则抛出PasswordException
	*如果API的消费者希望以特定的方式处理这个问题
	* @exception BiffException
	* @exception PasswordException
   */
  protected abstract void parse() throws BiffException, PasswordException;

  /**
		*关闭该工作簿,释放任何分配的内存
		*用于垃圾收集
   */
  public abstract void close();

  /**
	*一个工厂方法,它接受一个excel文件并读取其中的内容。
	* @exception IOException
	* @exception BiffException
	* @param文件excel 97电子表格解析
	* @return工作簿实例
   */
  public static Workbook getWorkbook(java.io.File file)
    throws IOException, BiffException
  {
    return getWorkbook(file, new WorkbookSettings());
  }

  /**
	*一个工厂方法,它接受一个excel文件并读取其中的内容。
	* @exception IOException
	* @exception BiffException
	* @param文件excel 97电子表格解析
	* @param ws工作簿的设置
	* @return工作簿实例
   */
  public static Workbook getWorkbook(java.io.File file, WorkbookSettings ws)
    throws IOException, BiffException
  {
    FileInputStream fis = new FileInputStream(file);
		//始终关闭输入流,不管是否
		//文件可以被解析感谢Steve Hahn
    File dataFile = null;

    try
    {
      dataFile = new File(fis, ws);
    }
    catch (IOException e)
    {
      fis.close();
      throw e;
    }
    catch (BiffException e)
    {
      fis.close();
      throw e;
    }

    fis.close();

    Workbook workbook = new WorkbookParser(dataFile, ws);
    workbook.parse();

    return workbook;
  }

  /**
		*一个工厂方法,它接受一个excel文件并读取其中的内容。
		* @param是一个开放的流,这是excel 97电子表格要解析
		* @return工作簿实例
		* @exception IOException
		* @exception BiffException
   */
  public static Workbook getWorkbook(InputStream is)
    throws IOException, BiffException
  {
    return getWorkbook(is, new WorkbookSettings());
  }

  /**
	*一个工厂方法,它接受一个excel文件并读取其中的内容。
	* @param是一个开放的流,这是excel 97电子表格要解析
	* @param ws工作簿的设置
	* @return工作簿实例
	* @exception IOException
	* @exception BiffException
   */
  public static Workbook getWorkbook(InputStream is, WorkbookSettings ws)
    throws IOException, BiffException
  {
    File dataFile = new File(is, ws);

    Workbook workbook = new WorkbookParser(dataFile, ws);
    workbook.parse();

    return workbook;
  }

  /**
	*使用给定的文件名创建一个可写的工作簿
	* @param文件的工作簿复制
	* @返回一个可写的工作簿
	* @exception IOException
   */
  public static WritableWorkbook createWorkbook(java.io.File file)
    throws IOException
  {
    return createWorkbook(file, new WorkbookSettings());
  }

  /**
	*使用给定的文件名创建一个可写的工作簿
	* @param file要复制的文件
	* @param ws全局工作簿设置
	* @返回一个可写的工作簿
	* @exception IOException
   */
  public static WritableWorkbook createWorkbook(java.io.File file,
                                                WorkbookSettings ws)
    throws IOException
  {
    FileOutputStream fos = new FileOutputStream(file);
    WritableWorkbook w = new WritableWorkbookImpl(fos, true, ws);
    return w;
  }

  /**
		创建一个可写的工作簿与给定的文件名作为副本通过的工作簿。一旦创建,可写的内容工作簿可能被修改
		@param file复制的输出文件
		@param在工作簿中复制
		@返回一个可写的工作簿
	  @exception IOException
   */
  public static WritableWorkbook createWorkbook(java.io.File file,
                                                Workbook in)
    throws IOException
  {
    return createWorkbook(file, in, new WorkbookSettings());
  }

  /**
		创建一个可写的工作簿与给定的文件名作为副本通过的工作簿。一旦创建,可写的内容工作簿可能被修改
		 @param file复制的输出文件
		 @param在工作簿中复制
		 @param ws此工作簿的配置
		 @返回一个可写的工作簿
   */
  public static WritableWorkbook createWorkbook(java.io.File file,
                                                Workbook in,
                                                WorkbookSettings ws)
    throws IOException
  {
    FileOutputStream fos = new FileOutputStream(file);
    WritableWorkbook w = new WritableWorkbookImpl(fos, in, true, ws);
    return w;
  }

  /**
		创建一个可写的工作簿作为副本通过的工作簿。一旦创建,可写的内容工作簿可能被修改
		@param OS要写入的流
		@param在工作簿中复制
		@返回一个可写的工作簿
		@exception IOException
   */
  public static WritableWorkbook createWorkbook(OutputStream os,
                                                Workbook in)
    throws IOException
  {
    return createWorkbook(os, in, ((WorkbookParser) in).getSettings());
  }

  /**
		创建一个可写的工作簿作为副本通过的工作簿。一旦创建,可写的内容工作簿可能被修改
		 @param OS要写入的输出流
		 @param在工作簿中复制
		 @param ws此工作簿的配置
		 @返回一个可写的工作簿
		 @exception IOException
   */
  public static WritableWorkbook createWorkbook(OutputStream os,
                                                Workbook in,
                                                WorkbookSettings ws)
    throws IOException
  {
    WritableWorkbook w = new WritableWorkbookImpl(os, in, false, ws);
    return w;
  }

  /**
		创建可写的工作簿。当工作簿关闭时,它将直接流到输出流。在这个
	  方式,一个生成的excel电子表格可以传递一个servlet到浏览器通过HTTP
	  @param OS输出流
		@返回可写的工作簿
		@exception IOException
   */
  public static WritableWorkbook createWorkbook(OutputStream os)
    throws IOException
  {
    return createWorkbook(os, new WorkbookSettings());
  }

  /**
		创建可写的工作簿。当工作簿关闭时,它将直接流到输出流。在这个
		方式,一个生成的excel电子表格可以传递一个servlet到浏览器通过HTTP
		@param OS输出流
		@param ws此工作簿的配置
		@返回可写的工作簿
		@exception IOException
   */
  public static WritableWorkbook createWorkbook(OutputStream os,
                                                WorkbookSettings ws)
    throws IOException
  {
    WritableWorkbook w = new WritableWorkbookImpl(os, false, ws);
    return w;
  }
}

WritableWorkbook类

       这个类的英文是 Writable Workbook "可写的工作簿",可见这个类是用来实现写操作的

public abstract class WritableWorkbook{
  /**
   * 单元格格式的默认字体
   */
  public static final WritableFont  ARIAL_10_PT =
    new WritableFont(WritableFont.ARIAL);

  /**
   * 用于超链接的字体
   */
  public static final WritableFont HYPERLINK_FONT =
    new WritableFont(WritableFont.ARIAL,
                     WritableFont.DEFAULT_POINT_SIZE,
                     WritableFont.NO_BOLD,
                     false,
                     UnderlineStyle.SINGLE,
                     Colour.BLUE);

  /**
   * 单元格的默认样式
   */
  public static final WritableCellFormat NORMAL_STYLE =
    new WritableCellFormat(ARIAL_10_PT, NumberFormats.DEFAULT);

  /**
   * 用于超链接的样式
   */
  public static final WritableCellFormat HYPERLINK_STYLE =
    new WritableCellFormat(HYPERLINK_FONT);

  /**
   * 用于隐藏单元格内容的单元格格式
   */
  public static final WritableCellFormat HIDDEN_STYLE = 
    new WritableCellFormat(new DateFormat(";;;"));

  /**
   * 由实现类使用的构造函数
   */
  protected WritableWorkbook()
  {
  }

  /**
		*获取此工作簿中的工作表。使用此方法为
		*大的工作表会导致性能问题。
		* @return单个表的数组
   */
  public abstract WritableSheet[] getSheets();

  /**
		*获取表单名称
		* @return一个包含工作表名称的字符串数组
   */
  public abstract String[] getSheetNames();

  /**
		*获取此工作簿中的指定工作表
		* @param index reQuired表的零索引
		* @return索引指定的工作表
		* @exception indexoutofboundexception当index指向一个不存在的对象时
   */
  public abstract WritableSheet getSheet(int index)
    throws IndexOutOfBoundsException;

  /**
		*从工作簿中获取具有指定名称的工作表
		* @param name表名
		* @return指定名称的工作表,如果没有找到则为空
   */
  public abstract WritableSheet getSheet(String name);

  /**
		*返回指定位置的单元格。“Sheet1 ! A4”。这与使用CellReferenceHelper与它的
		*相关的性能开销,因此它应该要节约使用
		* @param loc要检索的单元格
		* @return指定位置的单元格
   */
  public abstract WritableCell getWritableCell(String loc);

  /**
	*返回工作簿中的工作表数量
	* @返回工作簿中的工作表数量
   */
  public abstract int getNumberOfSheets();

  /**
		*关闭此工作簿,并使分配的任何内存可用
		*用于垃圾收集。也关闭底层的输出流,如果有必要。
		* @exception IOException
		* @exception WriteException
   */
  public abstract void close() throws IOException, WriteException;

  /**
		*创建并返回指定位置的工作表
		*与指定的名称
		*如果指定的索引小于或等于0,则新工作表
		在工作簿的开头创建。如果索引更大
		*大于工作表的数量,则工作表在
		*工作簿的结束。
		* @param name表名
		* @param index插入的索引号
		* @return new sheet
   */
  public abstract WritableSheet createSheet(String name, int index);

  /**
		*从不同的工作簿导入工作表。所有的都是深层拷贝吗
		*元素
		* @param name新工作表的名称
		* @param索引新工作表在工作簿中的位置
		* @param工作表(从另一个工作簿)合并到这个工作表
		* @return new sheet
   */
  public abstract WritableSheet importSheet(String name, int index, Sheet s);

  /**
		*在同一工作簿内的复制页。指定的工作表被复制到
		*该位置的新工作表名称
		* @param是要复制的页的索引
		* @param name新工作表的名称
		* @param索引新工作表的位置
   */
  public abstract void copySheet(int s, String name, int index);

  /**
		*复制指定的工作表并将其放在索引处
		*由参数指定
		* @param是要复制的表格的名称
		* @param name新工作表的名称
		* @param索引新工作表的位置
   */
  public abstract void copySheet(String s, String name, int index);

  /**
		*从工作簿中删除指定索引处的工作表
		* @param index要删除的表索引
   */
  public abstract void removeSheet(int index);

  /**
	*将工作簿中的指定工作表移动到另一个索引*位置。
	* @param from mindex所需表的零基础索引
	* @param toIndex要求的工作表的零基础索引
	* @返回已移动的表
   */
  public abstract WritableSheet moveSheet(int fromIndex, int toIndex);

  /**
		*以Excel格式写出工作簿中保存的数据
		* @exception IOException
   */
  public abstract void write() throws IOException;

  /**
		*指示该工作簿是否受保护
		* @param prot受保护标志
   */
  public abstract void setProtected(boolean prot);

  /**
		*设置工作簿的指定颜色的RGB值
		* @param c要覆盖其RGB值的颜色
		* @param r红色部分设置(0-255)
		* @param g绿色部分设置(0-255)
		* @param b蓝色部分设置(0-255)
   */
  public abstract void setColourRGB(Colour c, int r, int g, int b);

  /**
		*该方法可用于创建其他可写克隆
		*工作簿
		* @param w workdock to copy
		复制现在作为重载的一部分隐式发生
		*工厂方法workbook . createworkbook
   */
  public void copy(Workbook w)
  {
    //是一个抽象的方法——将方法主体留空吗
  }

  /**
	*从工作簿获取命名单元格。这个名字指的是一个
	*范围的单元格,则返回左上角的单元格。如果
	*名称不能为,返回null
	* @param name要搜索的单元格名称/范围
	* @返回范围左上角的单元格,如果找到,NULL
   */
  public abstract WritableCell findCellByName(String name);

  /**
		*从该工作簿获取指定的范围。Range对象返回
		*包含从左上到右下的所有单元格范围的*。
		*如果指定的范围包含相邻的范围,
		* Range[]将包含一个对象;对不相邻的
		*范围时,必须返回长度大于1的数组
		*如果指定范围包含单个单元格,则左上角和
		*右下角的单元格将是相同的单元格
		* @param name要搜索的单元格名称/范围
     返回单元格的范围
   */
  public abstract Range[] findByName(String name);

  /**
	*获取命名范围
	* @返回工作簿中命名单元格的列表
   */
  public abstract String[] getRangeNames();

  /**
		*从工作簿中移除指定的命名范围。请注意,
		删除名称可能导致使用该名称的公式
		错误地计算结果
		* @param name要删除的名称
   */
  public abstract void removeRangeName(String name);

  /**
		*添加新命名区域到工作簿与给定的信息。
		* @param name要创建的名称。
		* @param sheet包含名称的表
		* @param firstCol此名称所指的第一列。
		* @param firstRow这个名称所指的第一行。
		* @param lastCol此名称所指的最后一列。
		* @param lastRow这个名称所指的最后一行。
   */
  public abstract void addNameArea(String name,
                                   WritableSheet sheet,
                                   int firstCol,
                                   int firstRow,
                                   int lastCol,
                                   int lastRow);

  /**
		设置一个新的输出文件。这允许使用相同的工作簿
		*写入各种不同的输出文件而不必
		*再次读入任何模板
		* @param fileName文件名
		* @exception IOException
   */
  public abstract void setOutputFile(java.io.File fileName)
    throws IOException;
}

Sheet

       表示工作簿中的工作表。为个人提供句柄单元格或单元格行(按行或列分组)

public interface Sheet
{
  /**
		*返回在这行和这列指定的单元格。如果一个列/行组合是合并单元格组的一部分然后
		(除非它是组的第一个单元格)一个空白单元格将被退回
		* @param column列号
		* @param row行号
		* @return指定坐标的单元格
   */
  public Cell getCell(int column, int row);

  /**
	*返回指定位置的单元格。“A4”。请注意,这
	*方法与调用getCell(CellReferenceHelper.getColumn(loc)相同,
	* CellReferenceHelper.getRow(loc))及其隐式性能
	*字符串解析的开销。因此,这种方法应该
	要节约使用
	* @param loc单元格引用
	* @return指定坐标的单元格
   */
  public Cell getCell(String loc);

  /**
		*返回此工作表中的行数
		* @返回本表的行数
   */
  public int getRows();

  /**
		*返回此工作表的列数
		* @返回本页的列数
   */
  public int getColumns();

  /**
		*返回*中的列数获取指定行的所有单元格
		* @param row要返回单元格的行
		* @return表中给定行上的单元格
		* @返回本页的列数
   */
  public Cell[] getRow(int row);

  /**
	*获取指定列上的所有单元格
	* @param col要返回的单元格的列
	* @return指定列上的单元格
   */
  public Cell[] getColumn(int col);

  /**
		*获取指定列上的所有单元格
		* @param col the column获取工作表的名称
		* @return要返回单元格的表名
		* @return指定列上的单元格
   */
  public String getName();

  /**
		*确定工作表是否被隐藏
		* @返回是否隐藏表
		* @ getSettings()方法已弃用
   */
  public boolean isHidden();

  /**
		*确定工作表是否受保护
		* @返回表是否受保护
		* @ getSettings()方法已弃用
   */
  public boolean isProtected();

  /**
		*获取其内容与传入字符串匹配的单元格。如果没有找到匹配,则返回null。搜索被执行
		*以行为单位,所以行数越低,越多算法将有效执行
		* @param内容要匹配的字符串
		* @return其内容与参数匹配的Cell,如果没有找到则为空
   */
  public Cell findCell(String contents);

  /**
		*获取其内容与传入字符串匹配的单元格。如果没有找到匹配,则返回null。搜索被执行
		*以行为单位,所以行数越低,越多算法将有效执行
		* @param内容要匹配的字符串
		* @param firstCol范围内的第一列
		* @param firstRow范围的第一行
		* @param lastCol范围内的最后一列
		* @param lastRow范围内的最后一行
		* @param reverse表示是否执行反向搜索
		* @return其内容与参数匹配的Cell,如果没有找到则为空
   */
  public Cell findCell(String contents, 
                       int firstCol, 
                       int firstRow, 
                       int lastCol, 
                       int lastRow, 
                       boolean reverse);

  /**
		*获取其内容与传入的正则表达式字符串匹配的单元格。如果没有找到匹配,则返回null。搜索被执行
		*以行为单位,所以行数越低,越多算法将有效执行
		* @param pattern匹配的正则表达式字符串
		* @param firstCol范围内的第一列
		* @param firstRow表示数组的第一行
		* @param lastCol范围内的最后一列
		* @param lastRow范围内的最后一行
		* @param reverse表示是否执行反向搜索
		* @return其内容与参数匹配的Cell,如果没有找到则为空
   */
  public Cell findCell(Pattern pattern, 
                       int firstCol, 
                       int firstRow,
                       int lastCol,  
                       int lastRow, 
                       boolean reverse);

  /**
		*获取其内容与传入字符串匹配的单元格。如果没有找到匹配,则返回null。搜索被执行
		*以行为单位,所以行数越低,越多算法将有效执行。该方法不同
		在findCell方法中,只有带标签的单元格是查询-所有数字单元被忽略。这应该提高性能。
   * @param  contents the string to match
   * @return 内容与参数匹配的Cell,如果没有找到则为空
   */
  public LabelCell findLabelCell(String contents);

  /**
		*获取此工作表上的超链接
		* @return一个超链接数组
   */
  public Hyperlink[] getHyperlinks();

  /**
		*获取已在此工作表中合并的单元格
		* @return range对象的数组
   */
  public Range[] getMergedCells();

  /**
		*获取在特定工作表上使用的设置
		* @返回工作表设置
   */
  public SheetSettings getSettings();

  /**
		*获取指定列的列格式
		* @param col列号
		* @返回列的格式,如果列没有特定的格式,则返回NULL
		* @deprecated使用getColumnView和CellView bean代替
   */
  public CellFormat getColumnFormat(int col);

  /**
		*获取指定列的列宽度
		* @param col列号
		* @return列宽度,如果列没有宽度,则为默认宽度
		* 指定的格式
		* @deprecated使用getColumnView代替
   */
  public int getColumnWidth(int col);

  /**
		*获取指定列的列宽度
		* @param col列号
		* @return列格式,如果没有覆盖,则返回默认格式
		指定的
   */
  public CellView getColumnView(int col);

  /**
		*获取指定列的行高
		* @param row行号
		* @return行高度,如果列没有高度,则返回默认高度
		* 指定的格式
		* @deprecated使用getRowView代替
   */
  public int getRowHeight(int row);

  /**
		*获取指定列的行高
		* @param row行号
		* @return行格式,如果没有格式,可能是默认格式
		* 指定
   */
  public CellView getRowView(int row);

  /**
		*访问表上的图像数量
		* @返回本页图片的数量
   */
  public int getNumberOfImages();

  /**
		*图像访问器
		* @param I基于0的图像编号
		* @return指定位置的图像
   */
  public Image getDrawing(int i);

  /**
		*此页上分页符的访问器
		* @return本页的分页符
   */
  public int[] getRowPageBreaks();

  /**
	*此页上分页符的访问器
	* @return本页的分页符
   */
  public int[] getColumnPageBreaks();
}

源码看完了,简单操作感受一下

实体类

       为了方便最后发送Json给前端,所以这里就弄个实体类,把Excel当成数据库来用

    class ExcelDo{
        private String userName;        //姓名
        private String company;         //公司
    }//记得get set

读取操作

       由于读取Excel表,由于读出来的都是根据列的顺序来,为了不写一大堆的if,故使用循环来搞定。为了防止循环导致的数组越界,封装了一个辅助方法。第一次写,如果有更好的方法还望多多指教

   /**
     * 读取操作
     * @throws IOException
     * @throws BiffException
     */
  public List<ExcelDo> getExcelList() throws IOException, BiffException {
        List<ExcelDo> excelDoList = new ArrayList<ExcelDo>();                                //创建列表
        File xlsFile = new File("E:/ExcelProject/test.xls");                       //文件目录
        Workbook workbook = Workbook.getWorkbook(xlsFile);                                   //获得工作簿对象
        Sheet sheet = workbook.getSheet(0);                                            //获得工作表
        int rows = sheet.getRows();                                                          //获得行
        int cols = sheet.getColumns();                                                       //获得列
        int index = 0;
        for(int i = 0; i < rows; i++){                                                       //读取数据
            index = 0;
            ExcelDo excelDo = new ExcelDo();
            excelDo.setUserName(sheet.getCell(index,i).getContents());
            index = getIndex(index,cols);                                                   //每次添加完都调用一次
            excelDo.setCompany(sheet.getCell( index,i).getContents());
            excelDoList.add(excelDo);       //保存到列表中最后用来返回
        }
        workbook.close();
        return excelDoList;
    }
    /**
     * 循环时定义坐标,防止坐标越界 用于 辅助 getExcelList()
     * @param index
     * @param col
     * @return
     */
    private Integer getIndex(int index, int col){
        index++;
        if(index > col){
            index = col;
        }
        return index;
    }

测试

    public static void main(String[] args) throws IOException, BiffException{
        ExcelService excelService = new ExcelServiceImpl();
        List<ExcelDo> excelList = excelService.getExcelList();
        for(ExcelDo excelDo : excelList){
            System.out.println(excelDo.toString());
        }
    }

写操作

    /**
     * 添加数据
     * @param row       行数
     * @param col       列数
     * @param data       数据
     * @throws IOException
     * @throws WriteException
     */
    public void writeExcel(int row, int col,String data) throws IOException, WriteException {
        File xlsFile = new File("E:/ExcelProject/alvin.xls");
        // 创建一个工作簿
        WritableWorkbook workbook = Workbook.createWorkbook(xlsFile);
        // 创建一个工作表
        WritableSheet sheet = workbook.createSheet("Sheet1", 0);
        sheet.addCell(new Label(col, row, data));
        workbook.write();
        workbook.close();
    }

测试

    public static void main(String[] args) throws IOException, BiffException, WriteException {
        ExcelService excelService = new ExcelServiceImpl();
        excelService.writeExcel(2,2,"alvin");
    }

完整代码

package com.alvin.service.impl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.alvin.domain.ExcelDo;
import com.alvin.service.ExcelService;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.Sheet;
public class ExcelServiceImpl implements ExcelService{


    /**
     * 添加数据
     * @param row       行数
     * @param col       列数
     * @param data       数据
     * @throws IOException
     * @throws WriteException
     */
    public void writeExcel(int row, int col,String data) throws IOException, WriteException {
        File xlsFile = new File("E:/ExcelProject/alvin.xls");
        // 创建一个工作簿
        WritableWorkbook workbook = Workbook.createWorkbook(xlsFile);
        // 创建一个工作表
        WritableSheet sheet = workbook.createSheet("Sheet1", 0);
        sheet.addCell(new Label(col, row, data));
        workbook.write();
        workbook.close();
    }

    /**
     * 读取操作
     * @throws IOException
     * @throws BiffException
     */
  public List<ExcelDo> getExcelList() throws IOException, BiffException {
        List<ExcelDo> excelDoList = new ArrayList<ExcelDo>();                                //创建列表
        File xlsFile = new File("E:/ExcelProject/test.xls");                       //文件目录
        Workbook workbook = Workbook.getWorkbook(xlsFile);                                   //获得工作簿对象
        Sheet sheet = workbook.getSheet(0);                                            //获得工作表
        int rows = sheet.getRows();                                                          //获得行
        int cols = sheet.getColumns();                                                       //获得列
        int index = 0;
        for(int i = 0; i < rows; i++){                                                       //读取数据
            index = 0;
            ExcelDo excelDo = new ExcelDo();
            excelDo.setUserName(sheet.getCell(index,i).getContents());
            index = getIndex(index,cols);                                                   //每次添加完都调用一次
            excelDo.setCompany(sheet.getCell( index,i).getContents());
            excelDoList.add(excelDo);       //保存到列表中最后用来返回
        }
        workbook.close();
        return excelDoList;
    }

    /**
     * 循环时定义坐标,防止坐标越界 用于 辅助 getExcelList()
     * @param index
     * @param col
     * @return
     */
    private Integer getIndex(int index, int col){
        index++;
        if(index > col){
            index = col;
        }
        return index;
    }
}
  • 8
    点赞
  • 6
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:黑客帝国 设计师:我叫白小胖 返回首页

打赏作者

算法爱好者丶

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值