1、导出大量数据到excel
package com.sgcc.hpc.dc.util;import lombok.extern.slf4j.Slf4j;import org.apache.poi.ss.usermodel.*;import org.apache.poi.ss.util.CellRangeAddress;import org.apache.poi.xssf.streaming.SXSSFSheet;import org.apache.poi.xssf.streaming.SXSSFWorkbook;import java.io.FileOutputStream;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.util.HashMap;import java.util.Map;import java.util.concurrent.*;import java.util.concurrent.atomic.AtomicInteger;/** * @Author: 李孟帅 * @CreateTime: 2021/5/11$ 10:35$ * @Description: TODO */@Slf4jpublic class Poi { private final static DateTimeFormatter PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); private final SXSSFWorkbook workbook; private SXSSFSheet sheet; private final String fileName; private final AtomicInteger size = new AtomicInteger(0); public Poi(String fileName) { this.fileName = fileName; // 1.创建工作簿 // 阈值,内存中的对象数量最大值,超过这个值会生成一个临时文件存放到硬盘中 workbook = new SXSSFWorkbook(1000); } public AtomicInteger getSize() { return size; } public void createSheet() { createSheet("sheet" + workbook.getNumberOfSheets()); } public void createSheet(String sheetName) { //2.在Workbook中添加一个sheet,对应Excel文件中的sheet sheet = workbook.createSheet(sheetName); //3.设置样式以及字体样式 CellStyle titleCellStyle = createTitleCellStyle(); CellStyle headCellStyle = createHeadCellStyle(); //4.创建标题、表头,内容和合并单元格等操作 int rowNum = 0;// 行号 // 创建第一行,索引从0开始 Row row0 = this.sheet.createRow(rowNum++); row0.setHeight((short) 800);// 设置行高 String title = "这里是标题标题标题"; Cell c00 = row0.createCell(0); c00.setCellValue(title); c00.setCellStyle(titleCellStyle); // 合并单元格,参数依次为起始行,结束行,起始列,结束列 (索引0开始) this.sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 2)); // 第二行 Row row1 = this.sheet.createRow(rowNum++); row1.setHeight((short) 500); String[] row_first = {"采集点的标识", "采集点的值", "采集时间"}; for (int i = 0; i < row_first.length; i++) { Cell tempCell = row1.createCell(i); tempCell.setCellValue(row_first[i]); tempCell.setCellStyle(headCellStyle); } } private CellStyle createTitleCellStyle() { CellStyle cellStyle = createCellStyle(); cellStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.index); cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); return cellStyle; } private CellStyle createHeadCellStyle() { CellStyle cellStyle = createCellStyle(); cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index); cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); return cellStyle; } private CellStyle createCellStyle() { CellStyle cellStyle = workbook.createCellStyle(); cellStyle.setAlignment(HorizontalAlignment.CENTER); cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setBottomBorderColor(IndexedColors.BLACK.index); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setLeftBorderColor(IndexedColors.BLACK.index); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setRightBorderColor(IndexedColors.BLACK.index); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setTopBorderColor(IndexedColors.BLACK.index); return cellStyle; } public void write(BlockingQueue<Map<String, String>> queue) { try { // int rowNum = this.sheet.getLastRowNum() + 1; while (true) { Map<String, String> take = queue.take(); String code = take.get("code"); SXSSFSheet sheet = workbook.getSheet(code); if (sheet == null) { createSheet(code); } sheet = workbook.getSheet(code); int rowNum = sheet.getLastRowNum() + 1; Row tempRow = sheet.createRow(rowNum); tempRow.setHeight((short) 500); // 循环单元格填入数据 for (int j = 0; j < 3; j++) { Cell tempCell = tempRow.createCell(j); tempCell.setCellStyle(createCellStyle()); String tempValue; if (j == 0) { tempValue = take.get("code"); } else if (j == 1) { tempValue = take.get("value"); } else { tempValue = take.get("time"); } tempCell.setCellValue(tempValue); //设置列宽,必须在单元格设值以后进行 sheet.setColumnWidth(0, 4000); sheet.setColumnWidth(1, 3000); sheet.setColumnWidth(2, 3000); } int num = this.size.incrementAndGet(); if (num == 10000) { break; } } } catch (InterruptedException e) { log.warn(e.getMessage()); } } public void flush() { //导出 try { FileOutputStream outputStream = new FileOutputStream(fileName); workbook.write(outputStream); workbook.close(); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { LocalDateTime now = LocalDateTime.now(); ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); // ArrayBlockingQueue<Map<String, String>> queue = new ArrayBlockingQueue<>(1024); LinkedBlockingQueue<Map<String, String>> queue = new LinkedBlockingQueue<>(10240); ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); AtomicInteger index = new AtomicInteger(0); String basePath = "C:\\Users\\lms\\Desktop\\"; scheduledThreadPoolExecutor.scheduleAtFixedRate(() -> { // 当文件个数超过10个时,会覆盖旧的文件 if (index.get()==10){ index.set(0); } String fileName = basePath + "报表文件名称-" + index.incrementAndGet() + ".xlsx"; Poi poi = new Poi(fileName); long start = System.currentTimeMillis(); poi.write(queue); log.warn("数据10000条了,开始写入磁盘!"); poi.flush(); log.warn("写入excel时间:{}ms,队列中还有元素个数:{}", System.currentTimeMillis() - start, queue.size()); }, 10, 1000, TimeUnit.MILLISECONDS); while (true) { int count = 1; for (int i = 0; i < 10; i++) { HashMap<String, String> map = new HashMap<>(); String format = now.plusSeconds(count++).format(PATTERN); map.put("code", "inputRegister-1"); map.put("value", String.valueOf(i * 10 + 0.23)); map.put("time", format); queue.put(map); } for (int i = 8; i >= 0; i--) { HashMap<String, String> map = new HashMap<>(); String format = now.plusSeconds(count++).format(PATTERN); map.put("code", "inputRegister-2"); map.put("value", String.valueOf(i * 10 + 0.23)); map.put("time", format); queue.put(map); } Thread.sleep(10); // break; } }}
2、绘制xy散点图
package com.sgcc.lms.easypoi.util;import org.apache.poi.openxml4j.util.ZipSecureFile;import org.apache.poi.ss.usermodel.ClientAnchor;import org.apache.poi.ss.util.CellRangeAddress;import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;import org.apache.poi.xddf.usermodel.chart.*;import org.apache.poi.xssf.usermodel.XSSFChart;import org.apache.poi.xssf.usermodel.XSSFDrawing;import org.apache.poi.xssf.usermodel.XSSFSheet;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;public class XSSFUtils { public static void main(String[] args) throws Exception { String tmpFileName = "C:\\Users\\lms\\Desktop\\RTU采集数据_ankong_5.xlsx"; File file = new File(tmpFileName); System.out.println(file.exists()); InputStream fis = new FileInputStream(file); ZipSecureFile.setMinInflateRatio(-1.0d); XSSFWorkbook wb = new XSSFWorkbook(fis); // SXSSFWorkbook workbook = new SXSSFWorkbook(wb); XSSFSheet sheet = wb.getSheetAt(0); //创建一个画布 XSSFDrawing drawing = sheet.createDrawingPatriarch(); //前四个默认0,[5,20]:从5列0行开始;[0,15]:宽度15个单元格,15向下扩展到第15行 左上角[0,5] -> 右下角[15,20] ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 1, 20, 15); //创建一个chart对象 XSSFChart chart = drawing.createChart(anchor); //标题 chart.setTitleText("code"); //标题覆盖 chart.setTitleOverlay(false); //图例位置 XDDFChartLegend legend = chart.getOrAddLegend(); legend.setPosition(LegendPosition.TOP); //分类轴标(X轴),标题位置 //****** 如果是多条线,且X轴时数值类型的,切记::::要用XDDFValueAxis XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.TOP); bottomAxis.setTitle("time"); XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.BOTTOM); leftAxis.setTitle("value"); //CellRangeAddress(起始行号,终止行号, 起始列号,终止列号) //分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6] XDDFNumericalDataSource<Double> x = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 1600, 2, 2)); XDDFNumericalDataSource<Double> y = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 1600, 1, 1)); //scatter:XY散点图 XDDFScatterChartData scatter = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis); // 设置y轴刻度的样式 leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); XDDFScatterChartData.Series series1 = (XDDFScatterChartData.Series) scatter.addSeries(x, y); //条形图例标题 series1.setTitle("code", null); XDDFSolidFillProperties fill = new XDDFSolidFillProperties(); //条形图,填充颜色 series1.setFillProperties(fill); //绘制 chart.plot(scatter); FileOutputStream fileOut = new FileOutputStream(tmpFileName); wb.write(fileOut); wb.close(); }}