java通过poi读取word封装成实体类(docx)

POI在读写word docx文件时是通过xwpf模块来进行的,其核心是XWPFDocument。
一个XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档。
XWPFDocument中主要包含下面这几种对象:
  • XWPFParagraph:代表一个段落。
  • XWPFRun:代表具有相同属性的一段文本。
  • XWPFTable:代表一个表格。
  • XWPFTableRow:表格的一行。
  • XWPFTableCell:表格对应的一个单元格。

1.读docx文件 如果想要读取doc文件需要使用这个HWPFDocument对象,这里就不演示了,话不多说,上代码

1.1首先是依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
 <dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi</artifactId>
     <version>3.17</version>
 </dependency>
 <dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>3.17</version>
 </dependency>
 <!--如果想要操作doc文件还需要导入以下依赖-->
 <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.17</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.17</version>
</dependency>

java 代码,我这里因为特殊需要所以是批量读取的

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 读取文件
*/
public class ReadDir2 {
    public static void main(String[] args) throws IOException {
        //声明存放学校word文档的文件夹地址
        File file = new File("D:\\school");
        //去读取
        getAllFilePath(file);
    }

    /**
     * 遍历文件夹中的所有文件
     * @param dir
     * @throws IOException
     */
    public static List<Map<String,Object>> getAllFilePath(File dir) throws IOException {
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        File[] files=dir.listFiles();
        for(int i=0;i<files.length;i++){
            //判断当前是不是一个文件夹
            if(files[i].isDirectory()){
                System.out.println(files[i].getPath());
                //这里面用了递归的算法 如果是再递归调用自己  
                getAllFilePath(files[i]);
            } else {
                String path = files[i].getPath();
                String name = files[i].getName();
                map = DocxTest2.batchReadWord(path,name);
                list.add(map);
                //System.out.println("最终的结果");
                //System.out.println(map);
            }
        }
        return list;
    }
}
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 读取word文档数据
 */
public class DocxTest2 {

    //批量读取学校word文档数据
    public static Map<String, Object> batchReadWord(String path,String name) throws IOException {
        //读取第几个表
        Integer num = 0;
        InputStream is = new FileInputStream(path);
        XWPFDocument doc = new XWPFDocument(is);
        List<XWPFParagraph> paras = doc.getParagraphs();
        StringBuffer sb = new StringBuffer();
        for (XWPFParagraph para : paras) {
   
        	/**
        	 我这里是通过专门写了一个读取表格内容的方法 
        	 通过匹配到标题名字 就调用下面读取表格内容
        	*/
            //获取表格数据
            if (para.getText().equals("国家级(双一流)/部级/重点学科")){
                String table = getTable(doc,num);
                sb.append("国家级(双一流)/部级/重点学科:<p>"+table);
                num++;
                //读取完之后 num++ 这样下次再读取就会去找第二个表格的内容
                continue;
            }
            if (para.getText().contains("知名校友")){
                //获取表格数据
                String table = getTable(doc,num);
                sb.append("知名校友:<p>"+table);
                continue;
            }
            //每一段落的数据 para.getText() 这个方法会获取到word文档中每一个段落 获取到拼接起来
            //System.out.println(para.getText() + "是一段");
            sb.append(para.getText() + "<p>");
        }
			
        //程序执行到这里已经把word文档中完整数据全部读取到了
        Map<String,Object> map = new HashMap<>();
        // map.put("wanZheng",sb);
        map.put("name",name);
        
        //下面就去获取单独的数据获取单独数据
        Map<String, String> danDu = getDanDu(sb);
        //System.out.println(danDu);
        map.put("danDu",danDu);
        close(is);
        return map;
    }

    /**
     * 单独获取其中某一项的值
     * @param src
     */
    private static Map<String,String> getDanDu(StringBuffer src) {
        Map<String,String> map = new HashMap<>();
        // 1.获取“院校简介”的位置 
        Integer descPoi = src.indexOf("院校简介");
        // 2.获取学校属地及分校区的位置
        Integer shuDiPoi = src.indexOf("学校属地及分校区");
        // 3.截取包含院校简介的内容,并保存输出 通过上面两个索引就可以获得中间的段落
        //也就是属于简介的段落内容了
        String jianJie = src.substring(descPoi + "院校简介".length(), shuDiPoi);
        //System.out.println("简介:"+desc);
        map.put("jianJie",jianJie);

        // 4.获取【学校行政级别】的位置
        Integer jiBiePoi = src.indexOf("学校行政级别");
        // 5.截取包含学校属地及分区的内容,并保存输出
        String shuDi = src.substring(shuDiPoi + "学校属地及分校区".length()+1, jiBiePoi);
        //System.out.println("学校属地及分校区:"+shuDi);
        map.put("shuDi",shuDi);
		//..................下面依此类推,想到获取那部分内容就通过字符串截取的方式去得到他
		//然后把数据都封装到map中,最后通过get的方式依次赋值到实体类中
        return map;
    }


    /**
     * 获取表格内的数据
     * @param doc 文档源
     * @param num 第几个表格
     * @return
     */
    private static  String getTable(XWPFDocument doc,Integer num){
        //存放最后返回数据
        StringBuffer sb = new StringBuffer();
        //获取文档中所有的表格
        List<XWPFTable> tables = doc.getTables();
        //表格中所有的行
        List<XWPFTableRow> rows;
        //每一行所有的单元格
        List<XWPFTableCell> cells;
        sb.append("<table>");
        //获取到去读取第几个表格
        XWPFTable table = tables.get(num);
        //获取表格对应的行
        rows = table.getRows();
        for (XWPFTableRow row : rows) {
            //获取行对应的单元格
            cells = row.getTableCells();
            sb.append("<tr>");
            for (XWPFTableCell cell : cells) {
                sb.append("<td style='border: 1px solid black;'>" + cell.getText() + "</td>");
            }
            sb.append("</tr>");
        }
        sb.append("</table>");
        return sb.toString();
    }
    
    /**
     * 关闭输入流
     * @param is
     */
    private static void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

总结

		大致思路就是 ,首先通过
	    InputStream is = new FileInputStream(path);
        XWPFDocument doc = new XWPFDocument(is);
        List<XWPFParagraph> paras = doc.getParagraphs();
        这几个方法获取到所有的段落,通过字符串拼接的方式全部拼接起来,
        如果中间有表格的格式,就单独抽取一个方法去处理表格内容,也拼接起来
        最终得到一个完整内容的字符串,如果需要获取其中某一个段落,或者某几个段落
        就通过字符串的一系列索引,截取操作去获取到,最后还是要根据实际的情况去获取的
        这样就可以完成一个word文档数据封装到Java实体类的功能了,另外一定要注意,
        以上的方法是针对于docx的文档后缀,最后附上读取的文档格式

在这里插入图片描述

哦对了对了最后奉上的在做这个功能时觉得还不错的文章

https://www.iteye.com/blog/elim-2049110
https://blog.csdn.net/dongyuancaizi/article/details/78614217

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要引入POI的相关依赖包,并且要导入相关的类: ```java 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; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; ``` 然后,可以编写一个方法来读取Excel文件并将其转换为实体类: ```java public List<Entity> readExcel(File file) throws IOException { List<Entity> entities = new ArrayList<>(); FileInputStream inputStream = new FileInputStream(file); Workbook workbook = WorkbookFactory.create(inputStream); Sheet sheet = workbook.getSheetAt(0); for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); Entity entity = new Entity(); Cell cell1 = row.getCell(0); entity.setProperty1(cell1.getStringCellValue()); Cell cell2 = row.getCell(1); entity.setProperty2(cell2.getNumericCellValue()); Cell cell3 = row.getCell(2); entity.setProperty3(cell3.getStringCellValue()); entities.add(entity); } workbook.close(); inputStream.close(); return entities; } ``` 在这个方法中,我们首先打开Excel文件并获取第一个工作表。接下来,我们循环遍历每一行,并在每一行中获取每个单元格的值,并将其设置到实体类的属性中。最后,我们将实体类添加到列表中并返回列表。 需要注意的是,在这个方法中,我们假设Excel文件的第一行是表头,因此我们从第二行开始循环遍历。如果你的Excel文件没有表头,那么你需要从第一行开始循环,并相应地调整代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值