参考链接
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
获取一个段落中的所有Runs:List
获取一个Runs中的一个Run:XWPFRun run = xwpfRuns.get(index);
POI之word文档结构介绍之正文表格
一个文档包含多个表格,一个表格包含多行,一行包含多列(格),每一格的内容相当于一个完整的文档
获取所有表格:List
获取一个表格中的所有行:List
获取一行中的所有列:List
获取一格里的内容:List
之后和正文段落一样
注:表格的一格相当于一个完整的docx文档,只是没有页眉和页脚。里面可以有表格,使用xwpfTableCell.getTables()获取,and so on在poi文档中段落和表格是完全分开的,如果在两个段落中有一个表格,在poi中是没办法确定表格在段落中间的。(当然除非你本来知道了,这句是废话)。只有文档的格式固定,才能正确的得到文档的结构
POI之word文档结构介绍之页眉:
一个文档可以有多个页眉(不知道怎么会有多个页眉。。。),页眉里面可以包含段落和表格
获取文档的页眉:List
获取页眉里的所有段落:List
获取页眉里的所有表格:List
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等】的特点和限制,以便正确处理。
- 性能考虑: 在处理大量数据时,要注意性能问题,避免内存溢出等情况。