POI模板导出,操作word

  • 导出用户详情数据(图片,公式处理)
    • 使用模板导出用户详细信息
    • 使用模板引擎
      • 1.编写模板引擎
      • 2.使用模板引擎
  • 百万数据导出
    • 代码实现:
  • 百万数据导入
    • 步骤分析:
    • 1.自定义处理器
    • 2.自定义解析
    • 3.测试
  • CSV文件
    • 导出csv文件:
    • 读取csv文件
  • POI导出Word(.docx)
    • API介绍
    • 思路分析
    • 代码实现

Java-报表技术1-POI:https://blog.csdn.net/weixin_43994244/article/details/126227702

导出用户详情数据(图片,公式处理)

模板样式

使用模板导出用户详细信息

    //日期格式化private SimpleDateFormat simpleDateFormat = new  SimpleDateFormat("yyyy-MM-dd");/*** 导出用户详细信息--使用模板* @param id* @param response* @throws Exception*/public void downLoadUserInfoByTemplate(Long id, HttpServletResponse response) throws Exception {//1.读取模板//获取项目的根目录,创建目录---获取绝对路径File rootPath = new File(ResourceUtils.getURL("classpath:").getPath());File templateFile = new File(rootPath.getAbsolutePath(), "/excel_template/userInfo.xlsx");//创建有模板的工作簿Workbook workbook = new XSSFWorkbook(templateFile);Sheet sheet = workbook.getSheetAt(0);//2.获取用户数据User user = userMapper.selectByPrimaryKey(id);//3.数据放入模板---存入哪一行哪个单元格//用户名 第2行第2列sheet.getRow(1).getCell(1).setCellValue(user.getUserName());//手机号 第3行第2列sheet.getRow(2).getCell(1).setCellValue(user.getPhone());//生日 第4行第2列sheet.getRow(3).getCell(1).setCellValue(simpleDateFormat.format(user.getBirthday()));//工资 第5行第2列sheet.getRow(4).getCell(1).setCellValue(user.getSalary());//入职日期 第6行第2列sheet.getRow(5).getCell(1).setCellValue(simpleDateFormat.format(user.getHireDate()));//省份 第7行第2列sheet.getRow(6).getCell(1).setCellValue(user.getProvince());//城市 第7行第4列sheet.getRow(6).getCell(3).setCellValue(user.getCity());//现住址 第8行第1列---合并单元格sheet.getRow(7).getCell(1).setCellValue(user.getAddress());//司龄 第6行第4列---导出公式(入职时间到现在)// --填入excel的公式=CONCATENATE(DATEDIF(B6,TODAY(),"Y"),"年",DATEDIF(B6,TODAY(),"YM"),"个月")sheet.getRow(5).getCell(3).setCellFormula("CONCATENATE(DATEDIF(B6,TODAY(),\"Y\"),\"年\",DATEDIF(B6,TODAY(),\"YM\"),\"个月\")");//图片处理开始//照片--第二行到第五行,第三列到第四列--合并单元格String userPhoto = user.getPhoto();//先创建一个字节输出流ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//优化,获取拓展名,根据不同拓展名String extName = userPhoto.substring(userPhoto.lastIndexOf(".") + 1).toUpperCase();//读取图片,放入一个带有缓冲区的图片类中,主要作用是将一副图片加载到内存中BufferedImage bufferedImage = ImageIO.read(new File(rootPath+user.getPhoto()));//把图片写入到字节输出流中ImageIO.write(bufferedImage,extName,outputStream);//Patriarch图片写入Drawing patriarch = sheet.createDrawingPatriarch();//ClientAnchor指定图片位置--后四起始列,起始行,结束列,结束行,前四个参数,左上角向x,y偏离多少,右下角向x,y偏离多少(偏移单位-1cm=36w)  不占满表格ClientAnchor clientAnchor = new XSSFClientAnchor(0, 0, 0, 0, 2, 1, 4, 5);//优化int format = 0;switch (extName){case "JPG":{format = XSSFWorkbook.PICTURE_TYPE_JPEG;} case "JPEG":{format = XSSFWorkbook.PICTURE_TYPE_JPEG;} case "PNG":{format = XSSFWorkbook.PICTURE_TYPE_PNG;}}//开始把图片写入到sheet指定的位置patriarch.createPicture(clientAnchor,workbook.addPicture(outputStream.toByteArray(),format));//图片处理结束//4.下载//一个流两个头String fileName = "员工("+user.getUserName()+")详细数据.xlsx";response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));response.setContentType("application/vnd.ms-excel");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");//执行workbook.write(response.getOutputStream());}

使用模板引擎

前提:导出代码时,必须要提前知道要导出数据在哪一行哪一个单元格,但是模板一旦发生调整,java代码也要修改,所以可以自定义引擎,有了引擎即使模板修改了java代码也不用修改。
思路:在制作模板时,在需要插入数据的位置做上标记,在导出时,对象的属性和标记做对应,如果对应匹配一样,就把值赋值到相应的位置。

模板:

工具类: bean和map转换
可以借用hutool的BeanUtil里的方法:

此处是用jdk的API编写:
public class EntityUtils {private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");/*** 实体类转Map* @param object* @return*/public static Map<String, Object> entityToMap(Object object) {Map<String, Object> map = new HashMap();for (Field field : object.getClass().getDeclaredFields()){try {boolean flag = field.isAccessible();field.setAccessible(true);Object o = field.get(object);if(o instanceof Date){o = sdf.format(o);}map.put(field.getName(), o);field.setAccessible(flag);} catch (Exception e) {e.printStackTrace();}}return map;}/*** Map转实体类* @param map 需要初始化的数据,key字段必须与实体类的成员名字一样,否则赋值为空* @param entity 需要转化成的实体类* @return*/public static <T> T mapToEntity(Map<String, Object> map, Class<T> entity) {T t = null;try {t = entity.newInstance();for(Field field : entity.getDeclaredFields()) {if (map.containsKey(field.getName())) {boolean flag = field.isAccessible();field.setAccessible(true);Object object = map.get(field.getName());if (object!= null && field.getType().isAssignableFrom(object.getClass())) {field.set(t, object);}field.setAccessible(flag);}}return t;} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}return t;}
}

1.编写模板引擎

public class ExcelExportEngine {private static SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd");public static Workbook writeToExcel(Object object,Workbook workbook,String photoPath) throws Exception {//把bean转成mapMap<String, Object> map = EntityUtils.entityToMap(object);Sheet sheet = workbook.getSheetAt(0);Row row = null;Cell cell = null;//循环100行,每一行循环100个单元格---定位到具体的cellfor (int i = 0; i < 10; i++) {row = sheet.getRow(i);if(row == null){break;}else {for (int j = 0; j < 10; j++) {cell = row.getCell(j);if(cell != null){//比较单元格中的值,是否和map中的key一致,如果一致向单元格中放入map这个key对应的值writeToCell(cell,map);}}}}//处理图片if(StringUtils.isNotBlank(photoPath)){//File rootPath = new File(ResourceUtils.getURL("classpath:").getPath()); //SpringBoot项目获取根目录的方式ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();//BufferedImage是一个带缓冲区图像类,主要作用是将一幅图片加载到内存中BufferedImage bufferImg = ImageIO.read(new File(photoPath));ImageIO.write(bufferImg, "jpg", byteArrayOut);Drawing patriarch = sheet.createDrawingPatriarch();//获取模板图片位置Sheet sheet2 = workbook.getSheetAt(1);row = sheet2.getRow(0);int col1 = ((Double) row.getCell(0).getNumericCellValue()).intValue();int row1 = ((Double) row.getCell(1).getNumericCellValue()).intValue();int col2 = ((Double) row.getCell(2).getNumericCellValue()).intValue();int row2 = ((Double) row.getCell(3).getNumericCellValue()).intValue();//锚点,固定点ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0,  col1, row1, col2, row2);patriarch.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_JPEG));//删除第二个sheetworkbook.removeSheetAt(1);}return workbook;}//比较单元格中的值,是否和map中的key一致,如果一致向单元格中放入map这个key对应的值private static void writeToCell(Cell cell, Map<String, Object> map) {CellType cellType = cell.getCellType();//公式的话不处理switch(cellType){case FORMULA:{break;} default:{String cellValue = cell.getStringCellValue();if(StringUtils.isNotBlank(cellValue)){//System.out.println("获取到的cellValue"+cellValue);for (String key : map.keySet()){if(key.equals(cellValue)){cell.setCellValue(map.get(key).toString());//System.out.println("获取到的value:"+map.get(key).toString());}}}}}}
}

2.使用模板引擎

    /*** 导出用户详细信息--使用模板引擎* @param id* @param response* @throws Exception*/public void downLoadUserInfoByTemplate2(Long id, HttpServletResponse response) throws Exception {//1.读取模板//获取项目的根目录,创建目录---获取绝对路径File rootPath = new File(ResourceUtils.getURL("classpath:").getPath());File templateFile = new File(rootPath.getAbsolutePath(), "/excel_template/userInfo2.xlsx");//创建有模板的工作簿Workbook workbook = new XSSFWorkbook(templateFile);Sheet sheet = workbook.getSheetAt(0);//2.获取用户数据User user = userMapper.selectByPrimaryKey(id);System.out.println("获取到的用户信息"+user.toString());//3.通过自定义引擎放入数据--图片的绝对路径workbook = ExcelExportEngine.writeToExcel(user, workbook,rootPath.getPath()+user.getPhoto());patriarch.createPicture(clientAnchor,workbook.addPicture(outputStream.toByteArray(),format));//图片处理结束//4.下载//一个流两个头String fileName = "员工("+user.getUserName()+")详细数据.xlsx";response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));//xls//response.setContentType("application/vnd.ms-excel");//xlsxresponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");//执行workbook.write(response.getOutputStream());}

百万数据导出

用户模式: 用户模式有许多封装好的方法操作简单,但创建太多的对象,非常耗内存(之前使用的方法)
事件模式: 基于SAX方式解析XML,SAX全称Simple API for XML,它是一个接口,也是一个软件包。它是一种XML解析的替代方法,不同于DOM解析XML文档时把所有内容一次性加载到内存中的方式,它逐行扫描文档,一边扫描,一边解析。
SXSSF对象:是用来生成海量excel数据文件,主要原理是借助临时存储空间生成excel
弊端
1、不能使用模板
2、不能使用太多的样式
实现方式:
1.dom4j:一次性加载xml文件再解析
2.SAX:逐行加载,逐行解析
3.SXSSWorkBook:一旦内存中的对象的个数达到指定值时,就将内存中的这些对象的内容写入到磁盘中,就可以将这些对象从内存中销毁,直至excel导出完成。

代码实现:

   public void downLoadMillion(HttpServletResponse response) throws Exception {//使用sax方式解析Workbook workbook = new SXSSFWorkbook();//导出500w条数据,一个sheet只能放100w行//记录了处理了多少条数据int number = 0;//分页查询int page = 1;//记录row的行索引int rowIndex = 1;//创建行Row row = null;Sheet sheet = null;while (true) {List<User> userList = this.findPage(page, 1000000);if (CollectionUtils.isEmpty(userList)) {break;//数据为空不再查询}if (number % 1000000 == 0) {//表示应该创建新的标题sheet = workbook.createSheet("第" + (number/1000000)+ "个sheet表");//重置rowIndexrowIndex = 1;//设置列宽sheet.setColumnWidth(0,8*256);sheet.setColumnWidth(1,12*256);sheet.setColumnWidth(2,15*256);sheet.setColumnWidth(3,15*256);sheet.setColumnWidth(4,30*256);//设置小标题String[] title = new String[]{"编号", "姓名", "手机号", "入职日期", "现住址"};//创建标题行Row titleRow = sheet.createRow(0);for (int i = 0; i < 5; i++) {titleRow.createCell(i).setCellValue(title[i]);}}//向excel中添加内容for (User user : userList) {row = sheet.createRow(rowIndex);row.createCell(0).setCellValue(user.getId());row.createCell(1).setCellValue(user.getUserName());row.createCell(2).setCellValue(user.getPhone());row.createCell(3).setCellValue(simpleDateFormat.format(user.getHireDate()));row.createCell(4).setCellValue(user.getAddress());rowIndex++;number++;}page++;//下一页}//4.下载//一个流两个头String fileName = "百万数据导出.xlsx";response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");//执行workbook.write(response.getOutputStream());}

百万数据导入

用户模式: 加载并读取Excel时,是通过一次性的将所有数据加载到内存中再去解析每个单元格内容。当Excel数据量较大时,由于不同的运行环境可能会造成内存不足甚至OOM异常。
事件模式: 它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。

步骤分析:

1.设置POI的事件模式

  • 根据Excel获取文件流
  • 根据文件流创建OPCPackage ,用来组合读取到的xml 组合出来的数据占用的空间更小
  • 创建XSSFReader对象

2.Sax解析

  • 自定义Sheet处理器
  • 创建Sax的XmlReader对象
  • 设置Sheet的事件处理器
  • 逐行读取

1.自定义处理器

package com.itheima.test;import com.itheima.pojo.User;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {//    编号 用户名  手机号  入职日期 现住址private User user=null;@Overridepublic void startRow(int rowIndex) { //每一行的开始   rowIndex代表的是每一个sheet的行索引if(rowIndex==0){user = null;}else{user = new User();}}@Override  //处理每一行的所有单元格public void cell(String cellName, String cellValue, XSSFComment comment) {if(user!=null){String letter = cellName.substring(0, 1);  //每个单元名称的首字母 A  B  Cswitch (letter){case "A":{user.setId(Long.parseLong(cellValue));break;}case "B":{user.setUserName(cellValue);break;}}}}@Overridepublic void endRow(int rowIndex) { //每一行的结束if(rowIndex!=0){System.out.println(user);}}
}

2.自定义解析

package com.itheima.test;import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;import java.io.InputStream;/*** 自定义Excel解析器*/
public class ExcelParser {public void parse (String path) throws Exception {//1.根据Excel获取OPCPackage对象OPCPackage pkg = OPCPackage.open(path, PackageAccess.READ);try {//2.创建XSSFReader对象XSSFReader reader = new XSSFReader(pkg);//3.获取SharedStringsTable对象SharedStringsTable sst = reader.getSharedStringsTable();//4.获取StylesTable对象StylesTable styles = reader.getStylesTable();XMLReader parser = XMLReaderFactory.createXMLReader();// 处理公共属性:Sheet名,Sheet合并单元格parser.setContentHandler(new XSSFSheetXMLHandler(styles,sst, new SheetHandler(), false));XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) reader.getSheetsData();while (sheets.hasNext()) {InputStream sheetstream = sheets.next();InputSource sheetSource = new InputSource(sheetstream);try {parser.parse(sheetSource);} finally {sheetstream.close();}}} finally {pkg.close();}}
}

3.测试

用户模式下读取测试Excel文件直接内存溢出,测试Excel文件映射到内存中还是占用了不少内存;事件模式下可以流畅的运行。

public class POIDemo5 {public static void main(String[] args) throws Exception{new ExcelParser().parse("C:\\Users\\syl\\Desktop\\百万用户数据的导出.xlsx");}
}

CSV文件

CSV文件:Comma-Separated Values,中文叫逗号分隔值或者字符分割值,其文件以纯文本的形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分割。每条记录由字段组成,字段间的分隔符是其他字符或者字符串。所有的记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式。

用文本文件、excel或者类似与文本文件的编辑器都可以打开CSV文件。

使用opencsv类库来导出csv文
依赖:

<dependency><groupId>com.opencsv</groupId><artifactId>opencsv</artifactId><version>4.5</version>
</dependency>

opencsv常用API:

写入到csv文件会用到CSVWriter对象,创建此对象常见API如下:
CSVWriter(Writer writer);
CSVWriter(Writer writer, char separator);
CSVWriter(Writer writer, char separator, char quotechar);

构造器涉及到的三个参数:

  1. reader:读取文件的流对象,常有的是BufferedReader,InputStreamReader。
  2. separator:用于定义前面提到的分割符,默认为逗号CSVWriter.DEFAULT_SEPARATOR用于分割各列。
  3. quotechar:用于定义各个列的引号,有时候csv文件中会用引号或者其它符号将一个列引起来,例如一行可能是:“1”,“2”,“3”,如果想读出的字符不包含引号,就可以把参数设为:"CSVWriter.NO_QUOTE_CHARACTER "

使用CSVWriter对象写入数据常用的方法如下:
writerAll(List<String[]> allLines);
writerNext(String… nextLine);

读取csv文件会用到CSVReader对象,创建此对象常见API如下:
CSVReader(Reader reader)
CSVReader(Reader reader, char separator)
CSVReader(Reader reader, char separator, char quotechar)

导出csv文件:

   /*** 导出百万数据到CSV文件* @param response* @throws Exception*/public void downLoadCSV(HttpServletResponse response) throws Exception {ServletOutputStream outputStream = response.getOutputStream();//导出String fileName = "csv百万数据导出.csv";response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));response.setContentType("text/csv");//写文件CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(outputStream,"UTF-8"));//写第一行//设置小标题String[] title = new String[]{"编号", "姓名", "手机号", "入职日期", "现住址"};csvWriter.writeNext(title);int page = 1;while (true) {List<User> userList = this.findPage(1, 2000000);if(CollectionUtils.isEmpty(userList)){break;}for(User user : userList){csvWriter.writeNext(new String[]{user.getId().toString(),user.getUserName(),user.getPhone(),simpleDateFormat.format(user.getHireDate()),user.getAddress()});}page++;csvWriter.flush();}csvWriter.close();}

读取csv文件

import com.opencsv.CSVReader;import java.io.FileReader;
import java.text.SimpleDateFormat;
import java.time.Year;
import java.util.List;//读取百万级数据的csv文件
public class CsvDemo {`在这里插入代码片`private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");public static void main(String[] args) throws Exception {CSVReader csvReader = new CSVReader(new FileReader("d:\\百万用户数据的导出.csv"));String[] titles = csvReader.readNext(); //读取到第一行 是小标题
//        "编号","姓名","手机号","入职日期","现住址"User user = null;while (true){user = new User();String[] content = csvReader.readNext();if(content==null){break;}user.setId(Long.parseLong(content[0]));user.setUserName(content[1]);user.setPhone(content[2]);user.setHireDate(simpleDateFormat.parse(content[3]));user.setAddress(content[4]);System.out.println(user);}}
}

POI导出Word(.docx)

API介绍

XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档

一个文档包含多个段落,一个段落包含多个Runs文本,一个Runs包含多个Run,Run是文档的最小单元

获取所有段落:List paragraphs = word.getParagraphs();

获取一个段落中的所有片段Runs:List xwpfRuns = xwpfParagraph.getRuns();

获取一个Runs中的一个Run:XWPFRun run = xwpfRuns.get(index);

2、poi操作word中的表格

一个文档包含多个表格,一个表格包含多行,一行包含多列单元格

获取所有表格:List xwpfTables = doc.getTables();

获取一个表格中的所有行:List xwpfTableRows = xwpfTable.getRows();

获取一行中的所有列:List xwpfTableCells = xwpfTableRow.getTableCells();

获取一格里的内容:List paragraphs = xwpfTableCell.getParagraphs();

之后和正文段落一样

思路分析

制作一个word模板,把动态的内容先写特殊字符然后替换,表格自己创建然后向表格中放内容

代码实现

1.准备方法:一个是想指定的单元格中放入图片,另一个是 复制word中表格的行

    /*** 向单元格写入图片*/private void setCellImage(XWPFTableCell cell, File imageFile) {XWPFRun run = cell.getParagraphs().get(0).createRun();//流会自动关闭try(FileInputStream inputStream = new FileInputStream(imageFile)) {//输入流,图片类型,文件名,高度,宽度(图片扩大倍数)run.addPicture(inputStream,XWPFDocument.PICTURE_TYPE_JPEG,imageFile.getName(), Units.toEMU(100), Units.toEMU(50));} catch (Exception e) {e.printStackTrace();}}/*** 用户深复制行*/private void copyRow(XWPFTable table, XWPFTableRow sourceRow, int rowIndex) {XWPFTableRow targetRow = table.insertNewTableRow(rowIndex);//设置行属性targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());//获取源行的单元格--设置单元格属性List<XWPFTableCell> cells = sourceRow.getTableCells();//if(CollectionUtils.isEmpty(cells)){return;}XWPFTableCell targetCell = null;for (XWPFTableCell cell : cells) {targetCell = targetRow.addNewTableCell();//附上单元格的样式//单元格的样式targetCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());//单元个中段落属性targetCell.getParagraphs().get(0).getCTP().setPPr(cell.getParagraphs().get(0).getCTP().getPPr());}}

2.下载用户合同

    /*** 下载用户合同* @param id*/public void downloadContract(Long id,HttpServletResponse response) throws Exception {//1.读取到模板//获取项目的根目录,创建目录---获取绝对路径File rootPath = new File(ResourceUtils.getURL("classpath:").getPath());File templateFile = new File(rootPath.getAbsolutePath(), "word_template/contract_template.docx");XWPFDocument document = new XWPFDocument(new FileInputStream(templateFile));//2.查询当前用户--->map方便操作User user = this.findById(id);HashMap<String, String> hashMap = new HashMap<>();hashMap.put("userName",user.getUserName());hashMap.put("hireDate",simpleDateFormat.format(user.getHireDate()));hashMap.put("address",user.getAddress());//3.1.替换数据--处理正文List<XWPFParagraph> paragraphs = document.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {String text = run.getText(0);//循环遍历是否包含map的keyfor (String key : hashMap.keySet()) {if(text.contains(key)){//如果包含,替换掉run.setText(text.replaceAll(key,hashMap.get(key)),0);}}}}//3.2.表格数据List<Resource> resources = user.getResourceList();//获取表格XWPFTable table = document.getTables().get(0);//获取模板的第一行XWPFTableRow row = table.getRow(0);//存放东西,向表格中添加行int rowIndex = 1;for (Resource resource : resources) {//添加行//table.addRow(row);copyRow(table,row,rowIndex);XWPFTableRow tableRow = table.getRow(rowIndex);tableRow.getCell(0).setText(resource.getName());tableRow.getCell(1).setText(resource.getPrice().toString());tableRow.getCell(2).setText(resource.getNeedReturn()?"需要":"不需要");//照片处理File imageFile = new File(rootPath, "/static"+resource.getPhoto());setCellImage(tableRow.getCell(3),imageFile);rowIndex++;}//4.导出wordString fileName = "员工"+user.getUserName()+"合同.docx";response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");document.write(response.getOutputStream());}

报表技术2(百万数据导入导出,POI操作word)相关推荐

  1. POI报表及百万数据导入导出方案

    1.POI报表的概述 1.1 需求说明 在企业级应用开发中,Excel报表是一种最常见的报表需求.Excel报表开发一般分为两种形式:为了方便操作,基于Excel的报表批量上传数据:通过java代码生 ...

  2. 300万数据导入导出优化方案,从80s优化到8s(实测)

    前景 在项目开发中往往需要使用到数据的导入和导出,导入就是从Excel中导入到DB中,而导出就是从DB中查询数据然后使用POI写到Excel上. 写本文的背景是因为在工作中遇到了大数据的导入和导出,问 ...

  3. 高性能 + 百万级excel数据导入导出

    高性能 + 百万级excel数据导入导出 内容介绍 github地址 使用文档地址 安装注意事项 仅以mac举例 ide中提示相关代码 下载demo 内容介绍 [转载]https://learnku. ...

  4. JAVA语言(POI数据导入导出Excel)

    POI数据导入导出Excel(样式可以自己设置) //----------------------------Controller层 --------------------------------- ...

  5. JAVA实现数据库数据导入/导出到Excel(POI)

    原文地址为: JAVA实现数据库数据导入/导出到Excel(POI) 准备工作: 1.导入POI包:POI下载地址http://mirrors.tuna.tsinghua.edu.cn/apache/ ...

  6. 报表技术之Excel格式报表生成(POI)

    报表技术之Excel格式报表生成(POI) 1.找到你的页面的导出Excel的按钮 2.给导出按钮添加事件 3. 编写 ReportAction 添加 exportXls 方法 POI 生成 Exce ...

  7. [转载]在SQL Server数据库之间进行数据导入导出,OPENDATASOURCE

    需要在c盘下先建立一个data.txt文件,然后在文件的第一行写上你要导出的列,不如说要导出id和name这两列,就在第一行写上 id,name 然后保存,使用下列SQL就可以了,你如果要保持原有的I ...

  8. 利用sqoop将hive数据导入导出数据到mysql

    http://niuzhenxin.iteye.com/blog/1726414 运行环境  centos 5.6   hadoop  hive sqoop是让hadoop技术支持的clouder公司 ...

  9. ETL数据导入/导出工具 HData

    HData是一个异构的ETL数据导入/导出工具,致力于使用一个工具解决不同数据源(JDBC.Hive.HDFS.HBase.MongoDB.FTP.Http.CSV.Excel.Kafka等)之间数据 ...

最新文章

  1. 创建用户的SHELL小脚本
  2. 美图秀秀web开发文档
  3. Cookie 学习案例之三天免登录
  4. 管理系统中计算机应用怎么自学,有自学的没,管理系统中计算机应用上机题。...
  5. 华为机试HJ9:提取不重复的整数
  6. php curl 和 socket,PHP HTTP操作类 , 支持 Curl 和 Socket
  7. PDF内嵌字体分析 - 提取的文字是乱码原因分析
  8. python httpserver 支持ipv6
  9. 什么是IDE?新手用哪个IDE比较好?
  10. 对“淡泊以明志,宁静以致远”的理解
  11. 实习僧网站信息获取及字体解密
  12. TSRC挑战赛:WAF之SQL注入绕过挑战实录
  13. 那些你可能不知道的网易云音乐奇技淫巧
  14. 【Mysql系列】游标/光标简介
  15. linux minicon乱码,路径中带中文出现乱码问题
  16. GO语言 | go work 神一般的管理 多个module没烦恼
  17. 上云就上百度智能云,百度智能计算峰会召开,AI原生云全新升级
  18. 音视频开发(十四):OpenGL 与 OpenGL ES2区别
  19. 树莓派无源蜂鸣器c语言,[Python]使用树莓派+无源蜂鸣器播放铁血丹心
  20. Java 工程师岗位要求(支付)

热门文章

  1. 四款功能强大的优质app合集,总有一个能给你带来帮助!
  2. BOM:04-BOM有哪些形式?(按用途划分)
  3. android线程池!如何试出一个Android开发者真正的水平?内容太过真实
  4. 驭势“AI司机”融入城市生活,服贸会抢“鲜”体验
  5. 畅想X9BYOD式的生活
  6. python不间断爬取微博热搜并存储
  7. Redmi 游戏电视 X Pro 评测
  8. 转载-GNS3安装和使用教程(超详细)
  9. node aws 内存溢出_如何使用Node和AWS S3设置简单的图像上传
  10. C++最小/最大(min;max;minmax;min_element;max_element;minmax_element)