1 背景

  1. 需求:
    项目需求,导出excel或word;
    批量数据导入;
  2. 导入导出插件(API):

前端导出(jquery.wordexport.js、tableExport.js、Blob对象、xlsx等)
后端导出(poi、poi-tl、easypoi)

  1. 具体情况分析:
    简单导入导出、复杂(多数据)导入导出、带图片导入导出

2 前端导出

前提:只支持简单导出(内容少,不要求样式,只支持导出)

2.1 jquery.wordexport.js

引入js:

jquery.js
FileSaver.js    //处理图片
jquery.wordexport.js

使用

$("#showDIV").wordExport(FileName)

处理

function export() {var htmlstr = $("#page").html();//table所在div$('#printWord').html(htmlstr);$('#printWord div[data-role=pager]').remove();//把分页div删除$('#showDIV script').remove();//div引用的js代码删除$('#name').html(name);$("#showDIV").wordExport(FileName)
}
<div id="showDIV" style="display:none"><style>#printWord table {border: 1px solid #ddd;border-collapse: collapse;width: 95%;margin: auto;}#printWord table tr td {border: 1px solid #ddd;}#printWord table tr th {border: 1px solid #ddd;border-radius: 10px;}</style><h2 style="text-align: center;">隐患等级数量统计</h2><div style="text-align: right;margin-right: 50px; font-size: 16px;font-style: italic"><span style="color: blue;">标题</span>:<span id="name"></span></div><div id="printWord" />
</div>

博客:

html:https://www.cnblogs.com/wyl1924/p/9896448.html?ivk_sa=1024320u
vue:https://blog.csdn.net/MISS_CJL/article/details/89466710

2.2 tableExport.js

引入js:

jquery.js
FileSaver.js  //处理图片
tableExport.js
base64.js  //避免导出中文时乱码的js文件

使用

$("#btnExport").click(function(){$("table").tableExport({type: 'excel',ignoreRow: [1,2],//不导出的行:从0开始ignoreColumn: [5],//不导出的列:从0开始,忽略第5列 htmlContent: true,fileName: title,//文件名worksheetName: title,//sheet表的名字excelstyles: ['text-align', 'font-size', 'font-weight', 'line-height', 'border-collapse', 'height', 'overflow', 'white-space', 'text-overflow'],若table表格中使用了以下指定的样式属性,则将该样式同步到Excel中(可以保留表格原有的样式到Excel中)});
});

2.3 前端利用Blob实现文件导出

function daochu() {// 使用outerHTML属性获取整个table元素的HTML代码(包括<table>标签),然后包装成一个完整的HTML文档,设置charset为urf-8以防止中文乱码var html = "<html><head><meta charset='utf-8' /></head><body>" + document.getElementById("aaa").outerHTML + "</body></html>";html = html.replace("display: none", "");html = html.replace("table table-striped table-bordered table-condensed", "");// 实例化一个Blob对象,其构造函数的第一个参数是包含文件内容的数组,第二个参数是包含文件类型属性的对象var blob = new Blob([html], {type: "application/vnd.ms-excel"});var a = document.getElementById("print-click");//var textName = document.getElementById("biaoti").innerHTML;var textName = "整改意见";// 利用URL.createObjectURL()方法为a元素生成blob URLa.href = URL.createObjectURL(blob);// 设置文件名,目前只有Chrome和FireFox支持此属性a.download = textName + ".xls";a.click();
}
<div style="display: none;"><a id="print-click">超链接_导出表格</a>
</div>

type有以下选择:

1、“application/msword” Word
2、“application/vnd.ms-excel” Excel

2.4 xlsx插件导出(vue项目)

2.4.1 安装依赖

$ npm install -S file-saver
$ npm install -S xlsx

2.4.2 引入

import FileSaver from "file-saver";
import XLSX from "xlsx";

2.4.3 使用

exportExcel () {this.getData(() => {this.$nextTick(() => {let wb = XLSX.utils.table_to_book(document.querySelector("#out-table"));let wbout = XLSX.write(wb, {bookType: "xlsx",bookSST: true,type: "array",});try {FileSaver.saveAs(new Blob([wbout], { type: "application/octet-stream" }),"水质监测报告.xlsx");} catch (e) {if (typeof console !== "undefined") console.log(e, wbout);}return wbout;});});},

2.4 vue-json-excel导出(vue项目)

http://events.jianshu.io/p/f4195f2a23ee

3 后端导出——poi

3.1 依赖

<!-- poi office -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.9</version>
</dependency>

3.2 官方API

https://poi.apache.org/

4 POI操作excel

4.1 POI操作excel常用API

获得文档对象(工作簿):
xls: Workbook workbook= new HSSFWorkbook();
大数据量excel对象:Workbook workbook= new SXSSFWorkbook();
xlsx: Workbook workbook= new XSSFWorkbook();(常用)
Workbook workbook= new XSSFWorkbook(new FileInputStream());

获取工作表对象:
Sheet sheet = workbook.createSheet(“工作表名”);
Sheet sheet = workbook.getSheet(“工作表名”);
Sheet sheet = workbook.getSheetAt(索引);

获取行对象:
Row row = sheet.createRow(索引);
Row row = sheet.getRow(索引);

获取有效行:(如果sheet中一行数据都没有则返回-1,只有第一行有数据则返回0,最后有数据的行是第n行则返回 n-1)
int rowcount = sheet.getLastRowNum();

获取单元格对象:
Cell cell = row.createCell(索引)
Cell cell = row.getCell((short) 索引)

取得一行的有效单元格个数:(如果row中一列数据都没有则返回-1,只有第一列有数据则返回1,最后有数据的列是第n列则返回 n)
row.getLastCellNum();

设置行样式、字体:
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
cellStyle .setFont(font);
row.setRowStyle(CellStyle);

workbook(文件)=> sheet (表格) => row(行) => cell (单元格)

4.2 POI导出excel——示例工具类

public class ExportExcelUtil {public static void ExportExcel(List<Person> list, String[] titles) {SXSSFWorkbook wb = new SXSSFWorkbook();Sheet sheet = wb.createSheet();Row row = sheet.createRow(0);//给单元格设置样式CellStyle cellStyle = wb.createCellStyle();Font font = wb.createFont();//设置字体大小font.setFontHeightInPoints((short) 12);//设置字体加粗font.setBold(true);//给字体设置样式cellStyle.setFont(font);//设置单元格背景颜色cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//设置单元格填充样式(使用纯色背景颜色填充)cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);for (int i = 0; i < titles.length; i++) {Cell cell = row.createCell(i);cell.setCellValue(titles[i]);cell.setCellStyle(cellStyle);//设置列的宽度sheet.setColumnWidth(i, 200*50);}for (int j = 0; j < list.size(); j++) {Row rowData = sheet.createRow(j + 1);Person person = list.get(j);Cell cell = rowData.createCell(0);cell.setCellValue(person.getId());}String fileName = "D:/人员信息导出.xlsx";try {FileOutputStream fileOutputStream = new FileOutputStream(fileName);wb.write(fileOutputStream);wb.close();} catch (IOException e) {e.printStackTrace();}}
}

合并单元格

//合并单元格,参数依次为起始行、结束行、起始列、结束列
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 5, 0, 5);
sheet.addMergedRegion(cellRangeAddress);

包含图片

File file = new File(url) ;
if (file.exists()){BufferedImage bufferedImage = ImageIO.read(file) ;ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "jpg", byteArrayOut);//画图的顶级管理器,一个sheet只能获取一个(一定要注意这点)HSSFPatriarch patriarch = sheet1.createDrawingPatriarch();//anchor主要用于设置图片的属性(端锚)//HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)//dx1 dy1 起始单元格中的x,y坐标,dx2 dy2 结束单元格中的x,y坐标//col1,row1 指定起始的单元格,col2,row2 指定结束的单元格 XSSFClientAnchor anchor = new XSSFClientAnchor(10, 10, 990, 250, (short)0, 0, (short) 0, 0);drawingPatriarch.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
} else {cell.setCellType(XSSFCell.CELL_TYPE_STRING);cell.setCellValue("");
}

4.3 POI导出excel——基于自定义注解

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
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.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.google.common.collect.Lists;
import com.sunny.reverse.common.utils.Encodes;
import com.sunny.reverse.common.utils.Reflections;
import com.sunny.reverse.common.utils.excel.annotation.ExcelField;
import com.sunny.reverse.modules.sys.utils.DictUtils;/*** 导出Excel文件(导出“XLSX”格式,支持大数据量导出   @see org.apache.poi.ss.SpreadsheetVersion)* @author ThinkGem* @version 2013-04-21*/
public class ExportExcel {private static Logger log = LoggerFactory.getLogger(ExportExcel.class);/*** 工作薄对象*/private SXSSFWorkbook wb;/*** 工作表对象*/private Sheet sheet;/*** 样式列表*/private Map<String, CellStyle> styles;/*** 当前行号*/private int rownum;/*** 注解列表(Object[]{ ExcelField, Field/Method })*/List<Object[]> annotationList = Lists.newArrayList();/*** 构造函数* @param title 表格标题,传“空值”,表示无标题* @param cls 实体对象,通过annotation.ExportField获取标题*/public ExportExcel(String title, Class<?> cls){this(title, cls, 1);}/*** 构造函数* @param title 表格标题,传“空值”,表示无标题* @param cls 实体对象,通过annotation.ExportField获取标题* @param type 导出类型(1:导出数据;2:导出模板)* @param groups 导入分组*/public ExportExcel(String title, Class<?> cls, int type, int... groups){// Get annotation field Field[] fs = cls.getDeclaredFields();for (Field f : fs){ExcelField ef = f.getAnnotation(ExcelField.class);if (ef != null && (ef.type()==0 || ef.type()==type)){if (groups!=null && groups.length>0){boolean inGroup = false;for (int g : groups){if (inGroup){break;}for (int efg : ef.groups()){if (g == efg){inGroup = true;annotationList.add(new Object[]{ef, f});break;}}}}else{annotationList.add(new Object[]{ef, f});}}}// Get annotation methodMethod[] ms = cls.getDeclaredMethods();for (Method m : ms){ExcelField ef = m.getAnnotation(ExcelField.class);if (ef != null && (ef.type()==0 || ef.type()==type)){if (groups!=null && groups.length>0){boolean inGroup = false;for (int g : groups){if (inGroup){break;}for (int efg : ef.groups()){if (g == efg){inGroup = true;annotationList.add(new Object[]{ef, m});break;}}}}else{annotationList.add(new Object[]{ef, m});}}}// Field sortingCollections.sort(annotationList, new Comparator<Object[]>() {public int compare(Object[] o1, Object[] o2) {return new Integer(((ExcelField)o1[0]).sort()).compareTo(new Integer(((ExcelField)o2[0]).sort()));};});// InitializeList<String> headerList = Lists.newArrayList();for (Object[] os : annotationList){String t = ((ExcelField)os[0]).title();// 如果是导出,则去掉注释if (type==1){String[] ss = StringUtils.split(t, "**", 2);if (ss.length==2){t = ss[0];}}headerList.add(t);}initialize(title, headerList);}/*** 构造函数* @param title 表格标题,传“空值”,表示无标题* @param headers 表头数组*/public ExportExcel(String title, String[] headers) {initialize(title, Lists.newArrayList(headers));}/*** 构造函数* @param title 表格标题,传“空值”,表示无标题* @param headerList 表头列表*/public ExportExcel(String title, List<String> headerList) {initialize(title, headerList);}/*** 初始化函数* @param title 表格标题,传“空值”,表示无标题* @param headerList 表头列表*/private void initialize(String title, List<String> headerList) {this.wb = new SXSSFWorkbook(500);this.sheet = wb.createSheet("Export");this.styles = createStyles(wb);// Create titleif (StringUtils.isNotBlank(title)){Row titleRow = sheet.createRow(rownum++);titleRow.setHeightInPoints(30);Cell titleCell = titleRow.createCell(0);titleCell.setCellStyle(styles.get("title"));titleCell.setCellValue(title);sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),titleRow.getRowNum(), titleRow.getRowNum(), headerList.size()-1));}// Create headerif (headerList == null){throw new RuntimeException("headerList not null!");}Row headerRow = sheet.createRow(rownum++);headerRow.setHeightInPoints(16);for (int i = 0; i < headerList.size(); i++) {Cell cell = headerRow.createCell(i);cell.setCellStyle(styles.get("header"));String[] ss = StringUtils.split(headerList.get(i), "**", 2);if (ss.length==2){cell.setCellValue(ss[0]);Comment comment = this.sheet.createDrawingPatriarch().createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));comment.setString(new XSSFRichTextString(ss[1]));cell.setCellComment(comment);}else{cell.setCellValue(headerList.get(i));}sheet.autoSizeColumn(i);}for (int i = 0; i < headerList.size(); i++) {  int colWidth = sheet.getColumnWidth(i)*2;sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);  }log.debug("Initialize success.");}/*** 创建表格样式* @param wb 工作薄对象* @return 样式列表*/private Map<String, CellStyle> createStyles(Workbook wb) {Map<String, CellStyle> styles = new HashMap<String, CellStyle>();CellStyle style = wb.createCellStyle();style.setAlignment(CellStyle.ALIGN_CENTER);style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);Font titleFont = wb.createFont();titleFont.setFontName("Arial");titleFont.setFontHeightInPoints((short) 16);titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);style.setFont(titleFont);styles.put("title", style);style = wb.createCellStyle();style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);style.setBorderRight(CellStyle.BORDER_THIN);style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderLeft(CellStyle.BORDER_THIN);style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderTop(CellStyle.BORDER_THIN);style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderBottom(CellStyle.BORDER_THIN);style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());Font dataFont = wb.createFont();dataFont.setFontName("Arial");dataFont.setFontHeightInPoints((short) 10);style.setFont(dataFont);styles.put("data", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(CellStyle.ALIGN_LEFT);styles.put("data1", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(CellStyle.ALIGN_CENTER);styles.put("data2", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(CellStyle.ALIGN_RIGHT);styles.put("data3", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));
//      style.setWrapText(true);style.setAlignment(CellStyle.ALIGN_CENTER);style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setFillPattern(CellStyle.SOLID_FOREGROUND);Font headerFont = wb.createFont();headerFont.setFontName("Arial");headerFont.setFontHeightInPoints((short) 10);headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);headerFont.setColor(IndexedColors.WHITE.getIndex());style.setFont(headerFont);styles.put("header", style);return styles;}/*** 添加一行* @return 行对象*/public Row addRow(){return sheet.createRow(rownum++);}/*** 添加一个单元格* @param row 添加的行* @param column 添加列号* @param val 添加值* @return 单元格对象*/public Cell addCell(Row row, int column, Object val){return this.addCell(row, column, val, 0, Class.class);}/*** 添加一个单元格* @param row 添加的行* @param column 添加列号* @param val 添加值* @param align 对齐方式(1:靠左;2:居中;3:靠右)* @return 单元格对象*/public Cell addCell(Row row, int column, Object val, int align, Class<?> fieldType){Cell cell = row.createCell(column);String cellFormatString = "@";try {if(val == null){cell.setCellValue("");}else if(fieldType != Class.class){cell.setCellValue((String)fieldType.getMethod("setValue", Object.class).invoke(null, val));}else{if(val instanceof String) {cell.setCellValue((String) val);}else if(val instanceof Integer) {cell.setCellValue((Integer) val);cellFormatString = "0";}else if(val instanceof Long) {cell.setCellValue((Long) val);cellFormatString = "0";}else if(val instanceof Double) {cell.setCellValue((Double) val);cellFormatString = "0.00";}else if(val instanceof Float) {cell.setCellValue((Float) val);cellFormatString = "0.00";}else if(val instanceof Date) {cell.setCellValue((Date) val);cellFormatString = "yyyy-MM-dd HH:mm";}else {cell.setCellValue((String)Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), "fieldtype."+val.getClass().getSimpleName()+"Type")).getMethod("setValue", Object.class).invoke(null, val));}}if (val != null){CellStyle style = styles.get("data_column_"+column);if (style == null){style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"+(align>=1&&align<=3?align:"")));style.setDataFormat(wb.createDataFormat().getFormat(cellFormatString));styles.put("data_column_" + column, style);}cell.setCellStyle(style);}} catch (Exception ex) {log.info("Set cell value ["+row.getRowNum()+","+column+"] error: " + ex.toString());cell.setCellValue(val.toString());}return cell;}/*** 添加数据(通过annotation.ExportField添加数据)* @return list 数据列表*/public <E> ExportExcel setDataList(List<E> list){for (E e : list){int colunm = 0;Row row = this.addRow();StringBuilder sb = new StringBuilder();for (Object[] os : annotationList){ExcelField ef = (ExcelField)os[0];Object val = null;// Get entity valuetry{if (StringUtils.isNotBlank(ef.value())){val = Reflections.invokeGetter(e, ef.value());}else{if (os[1] instanceof Field){val = Reflections.invokeGetter(e, ((Field)os[1]).getName());}else if (os[1] instanceof Method){val = Reflections.invokeMethod(e, ((Method)os[1]).getName(), new Class[] {}, new Object[] {});}}// If is dict, get dict labelif (StringUtils.isNotBlank(ef.dictType())){val = DictUtils.getDictLabel(val==null?"":val.toString(), ef.dictType(), "");}}catch(Exception ex) {// Failure to ignorelog.info(ex.toString());val = "";}this.addCell(row, colunm++, val, ef.align(), ef.fieldType());sb.append(val + ", ");}log.debug("Write success: ["+row.getRowNum()+"] "+sb.toString());}return this;}/*** 输出数据流* @param os 输出数据流*/public ExportExcel write(OutputStream os) throws IOException{wb.write(os);return this;}/*** 输出到客户端* @param fileName 输出文件名*/public ExportExcel write(HttpServletResponse response, String fileName) throws IOException{response.reset();response.setContentType("application/octet-stream; charset=utf-8");response.setHeader("Content-Disposition", "attachment; filename="+Encodes.urlEncode(fileName));write(response.getOutputStream());return this;}/*** 输出到文件* @param fileName 输出文件名*/public ExportExcel writeFile(String name) throws FileNotFoundException, IOException{FileOutputStream os = new FileOutputStream(name);this.write(os);return this;}/*** 清理临时文件*/public ExportExcel dispose(){wb.dispose();return this;}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelField {/*** 导出字段名(默认调用当前字段的“get”方法,如指定导出字段为对象,请填写“对象名.对象属性”,例:“area.name”、“office.name”)*/String value() default "";/*** 导出字段标题(需要添加批注请用“**”分隔,标题**批注,仅对导出模板有效)*/String title();/*** 字段类型(0:导出导入;1:仅导出;2:仅导入)*/int type() default 0;/*** 导出字段对齐方式(0:自动;1:靠左;2:居中;3:靠右)*/int align() default 0;/*** 导出字段字段排序(升序)*/int sort() default 0;/*** 如果是字典类型,请设置字典的type值*/String dictType() default "";/*** 反射类型*/Class<?> fieldType() default Class.class;/*** 字段归属组(根据分组导出导入)*/int[] groups() default {};
}

使用

@ExcelField(title="名称", align=2, sort=3)
public String getName() {return name;}
new ExportExcel("数据", xxx.class).setDataList(list).write(response, fileName).dispose();

4.4 POI导入excel

public String import(MultipartFile file) {String fileName = file.getOriginalFilename();InputStream is = file.getInputStream();if(fileName.toLowerCase().endsWith("xls")){HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);sheet1 = hssfWorkbook.getSheetAt(0);}else if(fileName.toLowerCase().endsWith("xlsx")) {XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);sheet1 = xssfWorkbook.getSheetAt(0);}//getLastRowNum  如果sheet中一行数据都没有则返回-1,只有第一行有数据则返回0,最后有数据的行是第n行则返回 n-1;//getLastCellNum  如果row中一列数据都没有则返回-1,只有第一列有数据则返回1,最后有数据的列是第n列则返回 n;for (int i = 0; i <= sheet1.getLastRowNum(); i++) {Row row = sheet1.getRow(i);for (int j = 0; j < row.getLastCellNum(); j++){row.getCell((short) j).getStringCellValue();}}//合并单元格的值,就是合并单元格首行首列的值
}

5 POI操作word

5.1 POI操作word常用API

获取文件
HWPFDocument hwpfDocument = new HWPFDocument(); --doc 不建议使用
XWPFDocument xwpfDocument = new XWPFDocument(); --docx
XWPFDocument xwpfDocument = new XWPFDocument(new FileInputStream()); --docx

操作段落 document(文件)=> paragraph(段落) => run
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run=paragraph.createRun();
List paragraphs = document.getParagraphs();
List xwpfRuns = paragraphs .getRuns();
XWPFRun run = xwpfRuns.get(index);

操作表格 document(文件)=> table(段落) => row(行) => cell(单元格)
XWPFTable table = document.createTable();
XWPFTableRow row = table.createRow();
XWPFTableCell cell = row.createCell();
Lis tables = document.getTables();
List rows = table.getRows();
List tableCells = row.getTableCells();

建议大家使用 office word 来创建文档。(wps 和 word 结构有些不一样)
XWPFComment -------------------评论
XWPFFooter -------------------页脚
XWPFFootnotes -------------------脚注
XWPFHeader -------------------页眉
XWPFHyperlink -------------------超链接
XWPFNumbering -------------------编号
XWPFParagraph -------------------段落
XWPFPictureData -------------------图片
XWPFStyles -------------------样式(设置多级标题的时候用)
XWPFTable -------------------表格

5.2 POI导出word——直接导出示例

public void exportWord() {XWPFDocument document = new XWPFDocument();//文件XWPFParagraph paragraph;XWPFRun run;//建立段落paragraph = document.createParagraph();    //新建一个标题段落对象(就是一段文字)paragraph.setAlignment(ParagraphAlignment.CENTER);//样式居中run = paragraph.createRun();    //创建文本对象run.setBold(true); //加粗run.setColor("000000");//设置颜色run.setFontSize(25);    //字体大小run.setFontFamily("");//设置字体run.addBreak();    //换行run.setText("111");   //设置内容//建立表格XWPFTable table  = document.createTable(8,4);XWPFTableRow row;XWPFTableCell cell;CTTcPr cellPr;//单元格属性for(int j=0;j<8;j++){row = table.getRow(j);row.setHeight(600);for(int i=0;i<4;i++){//第一行cell = row.getCell(i);//建立单元格cell.setText("111");   //设置内容cellPr = cell.getCTTc().addNewTcPr();//单元格属性cellPr.addNewTcW().setW(BigInteger.valueOf(5000));//设置宽度cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);//垂直居中}}
}

5.3 POI导出word——模板导出示例

public void exportWord(String templatePath) {Map<String, String> dataMap = new HashMap<>(); //替换模板数据的map//模板文件流InputStream is = new FileInputStream(templatePath);XWPFDocument doc = new XWPFDocument(is);//遍历模板表格替换字段if (doc.getTables() != null){for (int a = 0; a < doc.getTables().size(); a++) { //循环表格XWPFTable table = doc.getTables().get(a);for (int i = 0; i < table.getNumberOfRows(); i++) {  //循环行XWPFTableRow row = table.getRow(i);List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {  //循环单元格//遍历集合进行替换for (String key : dataMap.keySet()) {  //循环替换数据if (cell.getText().equals(key)) {cell.removeParagraph(0);cell.setText(dataMap.get(key));//设置样式CTTcPr tcpr = cell.getCTTc().addNewTcPr();CTVerticalJc va = tcpr.addNewVAlign();va.setVal(STVerticalJc.CENTER);cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);}}}}}}
}

5.4 POI导出word——包含图片

推荐使用poi-tl

5.5 POI导入word

段落内容

InputStream is;
XWPFDocument doc = new XWPFDocument(is);
List<XWPFParagraph> paragraphs = doc.getParagraphs();
String text = paragraphs.get(0).getText();

表格内容

public void exportWord(String templatePath) {Map<String, String> dataMap = new HashMap<>(); //替换模板数据的map//模板文件流InputStream is = new FileInputStream(templatePath);XWPFDocument doc = new XWPFDocument(is);//遍历模板表格替换字段if (doc.getTables() != null){for (int a = 0; a < doc.getTables().size(); a++) { //循环表格XWPFTable table = doc.getTables().get(a);for (int i = 0; i < table.getNumberOfRows(); i++) {  //循环行XWPFTableRow row = table.getRow(i);List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {  //循环单元格cell.getText();}}}}
}

图片(未测试)

List<XWPFPictureData> allPictures = doc.getAllPictures();
for (XWPFPictureData picture : allPictures) {byte[] data = picture.getData();FileOutputStream out;out.write(data);out.close();
}

6.poi-tl(word模板)

6.1官网

http://deepoove.com/poi-tl/

6.2 依赖(必须有poi依赖,且注意版本对应)

<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.8.2</version>
</dependency>

6.3 介绍

Word模板支持DOCX格式,所有的标签都是以 {{ 开头,以 }} 结尾

6.4 使用

new ExportWord().export(new Object(), templatePath+"//wordTemplate//wordTemplate.docx",response);
public class ExportWord{public void export(Object object, String templatePath, HttpServletResponse response) throws IOException {Map<String, Object> mapData = getMapData(saveYearTaskVo);XWPFTemplate template = XWPFTemplate.compile(templatePath).render(mapData);this.write(template,"xxx.docx");}private static Map<String, Object> getMapData(Object object){Map<String, Object> data = new HashMap<>();data.put("name", object.getName());return data;}private void write(XWPFTemplate template,HttpServletResponse response, String fileName) throws IOException {String fileNameURL = URLEncoder.encode(fileName, "UTF-8");response.setCharacterEncoding("UTF-8");response.setHeader("Content-disposition", "attachment;filename=" + fileNameURL + ";" + "filename*=utf-8''" + fileNameURL);response.setContentType("application/octet-stream");//刷新缓冲response.flushBuffer();OutputStream ouputStream = response.getOutputStream();//doc将word写入到response的输出流中,供页面下载该word文件template.write(ouputStream);ouputStream.flush();ouputStream.close();}
}

6.5 图片模板

// 本地图片
put("localPicture", new PictureRenderData(120, 120, "./sayi.png"));// 图片流文件
put("localBytePicture", new PictureRenderData(100, 120, ".png", new FileInputStream("./logo.png")));// 网络图片
put("urlPicture", new PictureRenderData(100, 100, ".png", BytePictureUtils.getUrlBufferedImage("https://avatars3.githubusercontent.com/u/1394854")));// java 图片
put("bufferImagePicture", new PictureRenderData(100, 120, ".png", bufferImage)));

6.6 表格模板

RowRenderData header = RowRenderData.build(new TextRenderData("FFFFFF", "姓名"), new TextRenderData("FFFFFF", "学历"));RowRenderData row0 = RowRenderData.build("张三", "研究生");
RowRenderData row1 = RowRenderData.build("李四", "博士");
RowRenderData row2 = RowRenderData.build("王五", "博士后");put("table", new MiniTableRenderData(header, Arrays.asList(row0, row1, row2)));

7.easypoi

7.1 官网

https://gitee.com/lemur/easypoi
http://doc.wupaas.com/docs/easypoi/easypoi-1c0u4mo8p4ro8

7.2 使用

7.2.1 特点

1.设计精巧,使用简单
2.接口丰富,扩展简单
3.默认值多,write less do more
4.spring mvc支持,web导出可以简单明了

7.2.2 依赖

 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>3.2.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>3.2.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>3.2.0</version>
</dependency>

7.2.3 Excel导入导出

Excel的导入导出是Easypoi的核心功能,前期基本也是围绕这个打造的,主要分为三种方式的处理,其中模板和Html目前只支持导出,因为支持Map.class其实导入应该是怎样都支持的

  • 注解方式,注解变种方式
  • 模板方式
  • Html方式

7.2.4 注解方式导出示例

@ExcelTarget("teacherEntity")
public class TeacherEntity implements java.io.Serializable {/** name */@Excel(name = "主讲老师")private String name;
}
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("计算机一班学生","学生"),StudentEntity .class, list);
  • @Excel 作用到filed上面,是对Excel一列的一个描述
  • @ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
  • @ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段
  • @ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导导出
  • @ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理

8.Hutool

https://www.hutool.cn/
https://www.hutool.cn/docs/#/poi/Excel%E7%94%9F%E6%88%90-ExcelWriter?id=%e8%87%aa%e5%ae%9a%e4%b9%89excel

9.总结

注意:

  • poi-tl需要依赖poi,注意版本的对应
  • easypoi的依赖内部依赖原生的poi

8.1 优劣对比

8.1.1 前端导出

  • 优点:操作简单
  • 缺点:无法处理复杂样式、复杂数据

8.1.2 poi导入导出

  • 优点:能够处理几乎所有的导入导出功能
  • 缺点:导入导出的开发流程相对繁琐

8.1.3 poi-tl导出

  • 优点:操作简单,能够处理复杂的word导出
  • 缺点:只支持word导出

8.1.4 easypoi导入导出

  • 优点:操作简单
  • 缺点:

8.2 如何选择(个人理解)

  • 优先选择前端导出
  • 简单导出使用poi(基础)
  • 复杂导出使用poi-tl(word)或easypoi
  • 无法使用poi-tl或easypoi,回归poi

HZYWX-技术交流-开发中的导入导出相关推荐

  1. 开发指南专题十五 JEECG微云快速开发平台EXCEL导入导出

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴!  开 ...

  2. mysql navicat导入bcp_SQL Server中BCP导入导出用法详解

    bcp命令是SQL Server提供的一个快捷的数据导入导出工具.使用它不需要启动任何图形管理工具就能以高效的方式导入导出数据.bcp是SQL Server中负责导入导出数据的一个命令行工具,它是基于 ...

  3. 在IOS中实现导入导出文档

    导入&导出文档时IOS开发者经常面临的开发需求.例如你开发一个文档阅读器允许用户导入他的文档到你的应用中以便离线阅读.又如,你的阅读器可以导出文档以便其他应用使用. 这篇文章,将介绍各种IOS ...

  4. (译) 在IOS中实现导入导出文档

    导入&导出文档时IOS开发者经常面临的开发需求.例如你开发一个文档阅读器允许用户导入他的文档到你的应用中以便离线阅读.又如,你的阅读器可以导出文档以便其他应用使用.       这篇文章,将介 ...

  5. jeesite html导入excel,JeeSite中Excel导入导出

    在各种管理系统中,数据的导入导出是经常用到的功能,通常导入导出以Excel.CSV格式居多.如果是学习的过程中,最好是自己实现数据导入与导出的功能,然而在项目中,还是调用现成的功能比较好.近期一直使用 ...

  6. oracle中数据导入导出问题

    在日常生活中,我们有时难免要对一些系统进行移植,移植的时候,数据库中的数据问题就需要在不同的服务器上移动,这时就涉 及到数据的导入导出问题,这里我给大家介绍一些oracle数据的导入和导出问题. or ...

  7. Windows DLL编程中的导入导出:__declspec(dllimport) ,__declspec(dllexport) ,

    在Windows DLL编程时,可使用__declspec(dllimport)关键字导入函数或者变量. 函数的导入 当你需要使用DLL中的函数时,往往不需要显示地导入函数,编译器可自动完成.但如果你 ...

  8. C#窗体将DGV控件中数据导入导出Excel表

    目录 界面图: 效果视频: 一:将DGV数据导出到Excel表中 二:将Excel表数据导入到DGV中 三:界面全部代码 界面图: 效果视频: DGV数据导入导出Excel 一:将DGV数据导出到Ex ...

  9. ZSpace开发中PostProcess 导入

    遇到问题 在ZSpace开发中导入PostProcess插件发现会导致ZSpace中摄像机显示不正确,导致不能使用后处理效果. 解决方法 修改PostProcessingLayer.cs防止它干扰ZS ...

最新文章

  1. http_load安装与测试参数分析
  2. Grails示例程序-导出Excel文档
  3. 听说你想去大厂看妹子,带你看看腾讯产品运营实习面经
  4. 年入百万的 24 本理财秘籍,免费领取(速领)
  5. excel删除无尽空白行_excel如何批量删除空白行 巧用 ctrl+G 只需1秒 最常用的技巧...
  6. 编译原理0909的作业
  7. 开发之没沟通误删客户数据库数据之找数据路
  8. 从零学ELK系列(二):VMware安装Centos(超详细图文教程)
  9. Trufun Kant Studio 2008面向VS.NET的开发应用
  10. std::sort使用
  11. MATLAB2021下载安装图文教程
  12. 51单片机与蓝牙模块连接
  13. 科隆OPTIFLUX2100W/4100C分体式电磁流量计维修
  14. 【机器学习】朴素贝叶斯算法及其实现
  15. 【Computeshader】个人总结
  16. 零基础爬取堆糖网图片(一)
  17. C#(四十二)之线程同步、互锁
  18. curl命令及其API 的使用
  19. python list 对时间排序小结。
  20. 印能捷服务器中文字显示方块,修改Preps中文标记字体解决PJTF/JDF无法导入印能捷问题...

热门文章

  1. 【java毕业设计】基于javaEE+原生Servlet+SqlServer的医院管理住院系统设计与实现(毕业论文+程序源码)——医院管理住院系统
  2. BootLoader 介绍 与 uboot 简介
  3. [摘抄]给终身学习者的建议
  4. CAD打开多个文档只启动一个程序
  5. mysql mmm优缺点_mysql之MMM总结
  6. 百度地图分不同色块显示某个城市的行政区划,并添加城市(区)名
  7. 京东数科java一面【过】
  8. 你打英雄联盟or王者荣耀为什么老是匹配到怨种队友,进来看
  9. 每日自动签到签退的程序
  10. k8s Nodeport方式下service访问,iptables处理逻辑(转)