Apache POI java文档解析

参考链接

https://developer.aliyun.com/article/1309679
https://developer.aliyun.com/article/1321316?spm=a2c6h.14164896.0.0.42f147c56OBfGG
https://developer.aliyun.com/article/1335348?spm=a2c6h.14164896.0.0.42f147c56OBfGG
https://developer.aliyun.com/article/1325707?spm=a2c6h.14164896.0.0.42f147c56OBfGG
#.doc与.docx的介绍
https://www.howtogeek.com/304622/what-is-a-.docx-file-and-how-is-it-different-from-a-.doc-file-in-microsoft-word/?spm=a2c6h.12873639.article-detail.17.40553a42eVotNS 

Apache POI库简介

Apache POI(Poor Obfuscation Implementation)是Apache软件基金会开发的一款Java库,用于处理Microsoft Office格式的文档,包括Excel和Word文档。它提供了丰富的API,可以在Java应用中进行文档的读写、编辑和生成。

POI的特点

  • 全面支持: Apache POI库支持多种Microsoft Office格式,包括Excel、Word和PowerPoint等。
  • 功能丰富: Apache POI库提供了广泛的API,可以进行文档的读取、写入、编辑、格式化等操作。
  • 跨平台: Apache POI库是基于Java开发的,可以在各种平台上使用。
  • 社区活跃: Apache POI库拥有活跃的开源社区,持续更新和维护。

POI库的简单使用

        
        
            org.apache.poi
            poi
            4.1.2
        
        
            org.apache.poi
            poi-ooxml
            4.1.2
        
        
            org.apache.poi
            poi-ooxml-schemas
            4.1.2
        

Word

POI之word文档结构介绍之正文段落

一个文档包含多个段落,一个段落包含多个Runs,一个Runs包含多个Run,Run是文档的最小单元
获取所有段落:List paragraphs = word.getParagraphs();
获取一个段落中的所有Runs:List xwpfRuns = xwpfParagraph.getRuns();
获取一个Runs中的一个Run:XWPFRun run = xwpfRuns.get(index);

POI之word文档结构介绍之正文表格

一个文档包含多个表格,一个表格包含多行,一行包含多列(格),每一格的内容相当于一个完整的文档
获取所有表格:List xwpfTables = doc.getTables();
获取一个表格中的所有行:List xwpfTableRows = xwpfTable.getRows();
获取一行中的所有列:List xwpfTableCells = xwpfTableRow.getTableCells();
获取一格里的内容:List paragraphs = xwpfTableCell.getParagraphs();
之后和正文段落一样

注:表格的一格相当于一个完整的docx文档,只是没有页眉和页脚。里面可以有表格,使用xwpfTableCell.getTables()获取,and so on在poi文档中段落和表格是完全分开的,如果在两个段落中有一个表格,在poi中是没办法确定表格在段落中间的。(当然除非你本来知道了,这句是废话)。只有文档的格式固定,才能正确的得到文档的结构

POI之word文档结构介绍之页眉:

一个文档可以有多个页眉(不知道怎么会有多个页眉。。。),页眉里面可以包含段落和表格
获取文档的页眉:List headerList = doc.getHeaderList();
获取页眉里的所有段落:List paras = header.getParagraphs();
获取页眉里的所有表格:List tables = header.getTables();

docx文件内容读取

import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

public class ReadWordContent {

    public static void main(String[] args) throws Exception {
        String wordPath = "你的word文档地址.docx";
        ReadWordContent readWordContent = new ReadWordContent();
        readWordContent.readByExtractor(wordPath);
    }

    /**
     * 通过XWPFWordExtractor访问XWPFDocument的内容
     * @throws Exception
     */
    public void readByExtractor(String path) throws Exception {
        InputStream is = new FileInputStream(path);
        XWPFDocument doc = new XWPFDocument(is);
        XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
        String text = extractor.getText();
        System.out.println(text);

        /**
         * 打印文档信息
         */
        POIXMLProperties.CoreProperties coreProps = extractor.getCoreProperties();
        this.printCoreProperties(coreProps);
        this.close(is);
    }

    /**
     * 输出CoreProperties信息
     * @param coreProps
     */
    private void printCoreProperties(POIXMLProperties.CoreProperties coreProps) {
        String category = coreProps.getCategory(); //分类
        String creator = coreProps.getCreator(); //创建者,Microsoft Office User
        Date createdDate = coreProps.getCreated(); //创建时间
        String title = coreProps.getTitle(); //标题
        String description = coreProps.getDescription(); //描述,默认为null
        System.out.println(category);
        System.out.println(creator);
        System.out.println(createdDate);
        System.out.println(title);
        System.out.println(description);
    }

    /**
     * 关闭输入流
     * @param is
     */
    private void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

doc文档内容及格式读取

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.StyleDescription;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range;
import java.io.*;
/**
 * 注:HWPFDocument对应 word的.doc,不支持.docx
 */
public class ReadWordWithFormat {
    public static void main(String[] args) throws Exception {
        String filePath = "你的word文档地址.doc";
        printWord(filePath);
    }
    public static void printWord(String filePath) throws IOException {
        InputStream is = new FileInputStream(filePath);
        HWPFDocument doc = new HWPFDocument(is);
        Range r = doc.getRange();// 文档范围
        // System.out.println("段落数:"+r.numParagraphs());
        for (int i = 0; i < r.numParagraphs(); i++) {
            Paragraph p = r.getParagraph(i);// 获取段落
            int numStyles = doc.getStyleSheet().numStyles();
            int styleIndex = p.getStyleIndex();
            StyleSheet style_sheet = doc.getStyleSheet();
            StyleDescription style = style_sheet.getStyleDescription(styleIndex);
            String styleName = style.getName();
            // 打印各段落的格式
            System.out.println(i+","+styleIndex+","+styleName);
//            String styleLoving = "标题";
//            if (!StringUtils.isEmpty(styleName) && styleName.startsWith(styleLoving)){
//                String text = p.text();// 段落文本
//                System.out.println(text);
//            }
        }
        doc.close();
    }
}

导出word

创建 word 文档比较简单,直接使用 new XWPFDocument 即可,XWPFDocument 是对 .docx 文档操作的高级封装 API:

XWPFDocument doc = new XWPFDocument();

XWPFParagraph paragraph=doc.createParagraph(); //创建段落
paragraph.setAlignment(ParagraphAlignment.LEFT); //段落左对齐
XWPFRun run=titleParagraph.createRun();  //创建run
run.setBold(true); //粗体
run.setFontSize(15); //字号
run.setFontFamily("宋体"); //字体
run.setText("");  //输入内容
run.addBreak(); //换行

paragraph.setPageBreak(true);//分页


//创建一个表格,并指定宽度。wrod里面的表格
XWPFTable table = doc.createTable(4, 4);
TableTools.widthTable(table, MiniTableRenderData.WIDTH_A4_FULL, 4);

//设置第0行数据
List row0 = table.getRow(0).getTableCells();
row0.get(0).setText("xxxx"); //为第0行第0列设置内容
row0.get(0).setWidth("200");
row0.get(1).setText("aaaa");
row0.get(2).setText("bbbb");
row0.get(3).setText("cccc");


String path = "xxx.docx";
// 保存文档
FileOutputStream out = new FileOutputStream(path);
document.write(out);

out.close();
document.close(); 

Excel

读取Excel文件数据导入

    /**
     * 从excel中读取数据
     * @param xls        判断文件类型  true xls文件,false xlsx文件
     * @param inputStream 文件输入流
     * @return 数据封装到对象
     */
public List getDataFromExcel(boolean xls, InputStream inputStream) {
  SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Workbook workbook = null;
        //从Excel中要获取的数据
        ListstringList = new ArrayList<>(); 
        try {
            if (xls) {
                workbook = new HSSFWorkbook(inputStream);
            } else {
                workbook = new XSSFWorkbook(inputStream);
            }

            // 得到一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            // 得到表头
            Row rowHead = sheet.getRow(0);
            // 判断表头是否正确
            if (rowHead.getPhysicalNumberOfCells() < 1) {
                throw new Exception("表头错误");
            }

            // 获取数据
            for (int i = 2; i <= sheet.getLastRowNum(); i++) {
                // 获取第i行
                Row row = sheet.getRow(i);

                // 获取第i行各个列的空格数据
                String target = row.getCell(1).getStringCellValue();

                //获取完一行就存入列表
                stringList.add(target);

            }

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

        return stringList;
}

将数据导出Excel文件

    /**
     * 用于导出数据
     */
    public void exportStringToExcel() throws IOException {
        String filePath = "C:\\Users\\aog\\Desktop\\";
        String fileName = "导出数据表.xlsx";

        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet();

        workbook.setSheetName(0, "导出的数据");// 表单名

        //样式
        CellStyle headCellStyle = workbook.createCellStyle();//创建单元格样式对象
        Font font = workbook.createFont();
        font.setBold(false);// 是否加粗
        font.setFontHeightInPoints((short) 14);// 字体大小
        headCellStyle.setFont(font);
        headCellStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中

        //创建表头
        Row headRow = sheet.createRow(0);//创建第一行
        headRow.setHeightInPoints((2 * sheet.getDefaultRowHeightInPoints()));// 设置行高度
      
        // todo  获取所需要导出的数据
        ListstringList = new ArrayList<>(); 

        //从第一行开始填入数据
        int i = 0;

        //遍历全部数据·
        for (String str: stringList){

            //每个待导出的数据占有一行
            Row row = sheet.createRow(i);

            //写入Excel单元格
            for (int j = 0; j <= 2; j++) {
                Cell cell = row.createCell(j);
                cell.setCellStyle(headCellStyle);

                // 将值写入单元格
                cell.setCellValue(str);
            }
            // 行数+1
            i++;

        }

        //写入文件
        FileOutputStream fos = new FileOutputStream(filePath + fileName);
        workbook.write(fos);
        fos.flush();
        fos.close();
        workbook.close();
    }

注意事项

  • 文档格式: 在使用Apache POI库时,要了解不同文档格式【如doc,docx等】的特点和限制,以便正确处理。
  • 性能考虑: 在处理大量数据时,要注意性能问题,避免内存溢出等情况。

你可能感兴趣的:(Apache POI java文档解析)