列表导出excel+添加excel水印+消息队列(rabbitmq)实现记录
将导出列表请求发送到消息队列
//查询导出次数的逻辑代码省略 JSONObject data = new JSONObject(); data .element("userId", exportRecord.getUserId()); data .element("taskId", exportRecord.getTaskId());
//data是发送到消息队列的内容,Send用来发送消息 Send.execute(data.toString());
package com.seeyii.web.rabbitmq.send; import com.rabbitmq.client.BuiltinExchangeType; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.seeyii.web.rabbitmq.Constant; import net.sf.json.JSONObject; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Send { public static void execute(String data) { //创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置连接信息 factory.setHost(Constant.rabbitHost); factory.setPort(Constant.rabbitPort); factory.setUsername(Constant.rabbitUsername); factory.setPassword(Constant.rabbitPassword); factory.setVirtualHost("/"); Connection connection = null; Channel channel = null; try { //创建连接对象,用于连接到RabbitMQ connection=factory.newConnection(); //创建通道对象 channel=connection.createChannel(); // 声明exchange,参数1:交换机名称,参数2:交换机与消息队列的绑定方式,参数3:是否持久化,持久化可以将交换机存盘,在服务器重启时不会丢失相关信息 参数4:是否自动删除, 参数5;其他一些结构化参数,比如alternate-exchange channel.exchangeDeclare(Constant.exchangeName, BuiltinExchangeType.DIRECT,true,false,null); // 发送消息,并且指定routing key ,转发到不同队列 JSONObject msg = JSONObject.fromObject(data); String type = msg.getString("type"); //类型 associat.关联方导出 senior.高级搜索导出 equity.股权穿透导出 listExport.列表导出
//参数1(exchange ):交换机名, 当不使用交换机时,传入“”空串。参数2(routingKey):路由键. 参数3:消息的配置属性,例如 MessageProperties.PERSISTENT_TEXT_PLAIN 表示消息持久化 .参数4:消息数据本体, 必须是byte数组
channel.basicPublish(Constant.exchangeName, type,MessageProperties.PERSISTENT_TEXT_PLAIN, data.getBytes());
}
catch (IOException e) {
e.printStackTrace(); }
catch (TimeoutException e) {
e.printStackTrace(); }
finally {
if(channel != null){ try { channel.close(); }
catch (IOException e) {
e.printStackTrace(); }
catch (TimeoutException e) {
e.printStackTrace(); } }
if(connection != null){
try {
connection.close(); }
catch (IOException e) {
e.printStackTrace(); }
}
}
}
}
消息队列监听代码
package com.seeyii.web.rabbitmq.listener; import com.seeyii.web.rabbitmq.receive.Receive; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class RabbitListener implements ApplicationListener<ApplicationStartedEvent> { @Override public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) { System.out.println("************《rabbitmq监听开始》************"); try { Thread.sleep(5000); //关联方导出 Receive.execute(); //股权穿透导出 Receive.equityExecute(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
消息队列消费
package com.seeyii.web.rabbitmq.receive;
import com.rabbitmq.client.*; import com.seeyii.util.ValidateObject; import com.seeyii.web.download.service.RelatedService; import com.seeyii.web.rabbitmq.Constant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.IOException; import java.util.concurrent.TimeUnit; @Component public class Receive { @Autowired(required = false) RelatedService relatedService; @Autowired(required = false) static RelatedService relatedService2; @PostConstruct public void init() { relatedService=this.relatedService; relatedService2 = this.relatedService; } //关联方导出 public static void execute() throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost(Constant.rabbitHost); factory.setPort(Constant.rabbitPort); factory.setUsername(Constant.rabbitUsername); factory.setPassword(Constant.rabbitPassword);
// /是默认值 factory.setVirtualHost("/"); Connection connection = factory.newConnection(); final Channel channel = connection.createChannel();// 创建队列,参数1:对列名,参数2:是否持久化(队列持久化,消息持久化是在发消息时指定),参数3:是否排外,等于true的话用于一个队列只能有一个消费者来消费的场景
//参数4:是否自动删除队列(当最后一个消费者断开连接之后队列是否自动被删除,可以通过RabbitMQ Management,查看某个队列的消费者数量,当consumers = 0时队列就会自动删除,如果生产者声明了一个queue,此队列从来没有消费者连接过,那么 即使consumers = 0,队列也不会自动删除的) channel.queueDeclare(Constant.queueName, true, false, false, null); // 绑定队列到交换机,同时指定需要订阅的routing key。可以指定多个 channel.queueBind(Constant.queueName, Constant.exchangeName, "associat");//指定接收发送方指定routing key为associat的消息 // 指定该线程同时只接收一条消息 channel.basicQos(1); // 创建订阅器,并接受消息 DefaultConsumer consumer = new DefaultConsumer(channel) { public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); try { TimeUnit.MILLISECONDS.sleep(2000); if(ValidateObject.hasValue(message)){ // HandleMessage.execute(message); System.out.println("关联方导出rabbitmq message---->"+message); //列表导出excel代码 relatedService2.execute(message); } } catch (Exception e) { System.out.println(e); e.printStackTrace(); } finally { // 返回接收到消息的确认信息(手动ack) channel.basicAck(envelope.getDeliveryTag(), false); } } }; // 打开消息应答机制 channel.basicConsume(Constant.queueName, false, consumer); } //股权穿透导出 public static void equityExecute() throws Exception { //逻辑相同,省略 } public void execute(String message) {
try {if(type==0){//关联方列表导出 System.out.println("-------------------关联方列表开始导出--------------------"); List<JSONObject> dataList = null; boolean flag = true; int pageNum = 0; // 开始下标数量 int numPerPage = 1000; // 请求条数 while(flag){ dataList = relatedPartiesList(companyName, allCompanyNames, compType, relatedType,pageNum, numPerPage);//从数据库查出的列表数据,每次查一页的数据,通过while循环添加到 resultList里 Thread.sleep(666); if(ValidateObject.hasValueInCollection(dataList)){ resultList.addAll(dataList); } else { flag = false; } if(ValidateObject.hasValueInCollection(dataList)){ if(dataList.size() == numPerPage){ pageNum += numPerPage; flag = true; } else { flag = false; } } } }else if(type==2){//股东穿透列表导出 //逻辑相同,代码省略 } if(!ValidateObject.hasValueInCollection(resultList)){ return; } String url = createExcelExport(type,fileType,fileName,titleList, exportFieldList, resultList); System.out.println("url----> "+url); ExportRecord exportRecord4 = new ExportRecord(); exportRecord4.setUserId(userId); exportRecord4.setTaskId(taskId); exportRecord4.setPtNo(ptNo);//平台编号 exportRecord4.setStatus(1);//导出成功 exportRecord4.setUrl(url);//文件下载地址 exportRecord4.setResultTotal(String.valueOf(resultList.size()));//记录结果条数 // 生成文件成功后更新数据库 boolean success = downloadService.updateExport(exportRecord4); System.out.println("---->is success"+success); if(success){ System.out.println("修改成功!!!!!!"); } } catch (Exception e) { System.out.println(e); e.printStackTrace(); // 对数据进行异常修改 downloadService.updateExport(exportRecord2); }finally { long endTime = System.currentTimeMillis(); String endTimes = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); System.out.println("开始时间: " + currentTimes + " ,结束时间:"+endTimes); System.out.println("导出耗时: " + (endTime - startTime) / 1000 + " s"); } }
列表导出方法:
public static String createExcelExport(int type,String fileType,String fileName,List<String> titleList, List<String> exportFieldList, List<JSONObject> dataList){ //创建一个EXCEL XSSFWorkbook wb = new XSSFWorkbook(); //Workbook wb = new HSSFWorkbook(); // DataFormat format = wb.createDataFormat(); //创建一个SHEET XSSFSheet sheet1 = wb.createSheet(EnumListType.getEnumName(type)); BufferedImage image = null; try { ClassPathResource resource = new ClassPathResource("sysconfig/bg-water-mark-small.png");//resources路径下 InputStream inputStream= resource.getInputStream(); //System.out.println(path); image = ImageIO.read(inputStream); } catch (IOException e) { e.printStackTrace(); } // 导出到字节流B ByteArrayOutputStream os = new ByteArrayOutputStream(); try { ImageIO.write(image, "png", os); } catch (IOException e) { e.printStackTrace(); } int pictureIdx = wb.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG); // is.close(); //add relation from sheet to the picture data String rID = sheet1.addRelation(null, XSSFRelation.IMAGES, wb.getAllPictures().get(pictureIdx)).getRelationship().getId(); // String rid = sheet.addRelation(null,XSSFRelation.IMAGES,workbook.getAllPictures().get(pictureIdx)) //set background picture to sheet sheet1.getCTWorksheet().addNewPicture().setId(rID); //设置默认宽度、高度值 sheet1.setDefaultColumnWidth(15); sheet1.setDefaultRowHeightInPoints(20); sheet1.createFreezePane(0, 1, 0, exportFieldList.size()); // 冻结首行 //创建一行 Row row_1 = sheet1.createRow((short)0); CellStyle style = wb.createCellStyle(); // style.setWrapText(true); // 设置自动换行 // 字体颜色 XSSFFont font = wb.createFont(); font.setColor(IndexedColors.BLACK.getIndex()); // 字体颜色 font.setFontHeightInPoints((short)12); // 字体大小 // font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 字体加粗 style.setFont(font); //填充标题 int num = 0; for (String s : titleList) { Cell cell = row_1.createCell(num); cell.setCellValue(s); cell.setCellStyle(style); num++; } // 开始填充数据行 int row_index = 1; // 定义行游标 int cell_index = 0; // 定义单元格游标 for(JSONObject data : dataList){ Row row = sheet1.createRow((short)row_index); for(String fields : exportFieldList){ if(data.containsKey(fields)){ row.createCell(cell_index).setCellValue(data.get(fields)+""); } cell_index++; } cell_index = 0; // 清空游标 row_index ++; } System.out.println("表格生成结束……开始上传服务器……"); long startTime = System.currentTimeMillis(); FileOutputStream fileOut = null; InputStream in = null ; String file_name = null; // 文件夹名称 String logoPath = ""; // 上传阿里云返回文件名称 // 临时丢到tomcat下 try { ApplicationHome ah = new ApplicationHome(RelatedServiceImpl.class); String tempfilePath =ah.getSource().getParentFile().toString()+ tempfileFile; if("xlsx".equals(fileType)||"xls".equals(fileType)){ file_name = System.currentTimeMillis()+".xls"; } File file = new File(tempfilePath); if(file.exists()){ fileOut = new FileOutputStream(tempfilePath + "\\" + file_name ); } else { file.mkdir(); // 选择生成文件地址 fileOut = new FileOutputStream(tempfilePath + "\\" + file_name); } wb.write(fileOut); fileOut.flush(); fileOut.close(); // 进行上传阿里云服务器操作 TimeUnit.MILLISECONDS.sleep(2000); in = new BufferedInputStream(new FileInputStream(tempfilePath + "\\" + file_name)); byte[] file_byte; // 上传到相应的阿里云文件服务器 String uuid = UUID.randomUUID().toString().replace("-", ""); file_byte = UploadOSS.input2byte(in); String url = Encrypter.BASE64Encoder(file_byte); logoPath = UploadOSS.uploadHeadPicByOSS2(uuid, url,fileName,type,fileType); System.out.println( "上传阿里云生成的ecxel文件名称:" + logoPath ); in.close(); // 删除项目下的临时生成的 ecxel 文件 deleteFile(tempfilePath + "\\" + file_name); long endTime = System.currentTimeMillis(); System.out.println("time: " + (endTime - startTime) / 1000 + " s"); } catch (Exception e) { e.printStackTrace(); } finally { try { if (fileOut != null) { fileOut.flush(); fileOut.close(); } if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } return logoPath; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)