首页
友链
统计
留言
关于
Search
1
Java生成二维码——基于Google插件
125 阅读
2
Java使用poi-tl动态生成word和pdf
121 阅读
3
网站声明
98 阅读
4
利用Spring的InitializingBean优雅的实现策略模式
88 阅读
5
循环单链表及其实现
82 阅读
默认分类
Java
C语言
数据库技术
Linux
前端
其他
登录
/
注册
Search
标签搜索
C语言
数据结构
Java
Spring
数据库技术
MySQL
Hadoop
MapReduce
大数据
easyExcel
POI
MybatisPlus
AOP
SpringMVC
IDEA
工厂模式
策略模式
设计模式
LiXiangrong
累计撰写
57
篇文章
累计收到
151
条评论
首页
栏目
默认分类
Java
C语言
数据库技术
Linux
前端
其他
页面
友链
统计
留言
关于
搜索到
11
篇与
的结果
2024-11-01
配置Windows11系统环境下MapReduce本地调试样例
1.下载hadoopapache官网下载hadoop,Index of /dist/hadoop/common (apache.org),这里以配置hadoop-3.2.2为例,点击版本号进入选择对应压缩包下载下载后解压到非中文目录下,例如:D:\develop\hadoop-3.2.22.下载winutils(windows下编译的hadoop执行文件)下载地址: https://github.com/cdarlint/winutils下载后解压进入与hadoop对应版本的文件夹,将bin目录下的文件粘贴到刚才解压的hadoop的bin目录下,粘贴时选择“替换目标中的文件”。3.配置环境变量1.打开设置,找到系统设置中的高级系统设置,选择修改环境变量,新建变量名为HADOOP_HOME的系统变量,变量值为刚才下载并解压的hadoop的存放目录。2.编辑Path变量双击Path变量,新增如下两条:%HADOOP_HOME%\bin%HADOOP_HOME%\sbin最后点击确定并应用4.检查环境变量是否配置正确使用hadoop需要首先安装并正确配置jdk。打开cmd命令行工具,输入java -version和hadoop -version,如能正确显示jdk版本即表示安装配置正确,否则请检查jdk安装和配置,hadoop配置等。
2024年11月01日
13 阅读
0 评论
0 点赞
2024-04-15
springboot整合easyExcel导出excel
1. 引入依赖<!--excel读写--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.3.2</version> </dependency>2.导出工具public class ExportUtil { public static final Logger LOGGER = LoggerFactory.getLogger(ExportUtil.class); private static final String WORD = ".docx"; private static final String PDF = ".pdf"; private static final String XLSX = ".xlsx"; private static final String TYPE = "application/octet-stream"; private static final String HEADER_K = "Content-disposition"; private static final String HEADER_V = "attachment;filename="; /** * @Author LiXiangrong * @Description 导出Excel到web流 * @Date 2024/04/02 9:37:07 * @param clazz 导出目标类 * @param response 浏览器响应 * @param fileName 文件名末尾会自动拼上导出时间 * @param sheetName sheetName * @param dataList 数据集合 * @Return void **/ public static void exportExcel(Class<?> clazz, HttpServletResponse response, String fileName,String sheetName, List<?> dataList) { try { String DateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒")); fileName = URLEncoder.encode(fileName+DateTime,"UTF-8").replaceAll("\\+", "%20"); response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); response.setHeader(HEADER_K, "attachment;filename*=utf-8''" + fileName + XLSX); EasyExcel.write(response.getOutputStream(),clazz) .excelType(ExcelTypeEnum.XLSX) .sheet(sheetName) .doWrite(dataList); } catch (IOException e) { e.printStackTrace(); LOGGER.error("导出{}Excel失败",fileName, e); throw new DataException("导出Excel失败"); } } }3.在控制层查询导出数据并使用导出工具导出到web@ApiOperation("XXX导出") @PostMapping("/xxxExport") public void exportExcel(HttpServletResponse response,@RequestBody JProjectSupervisePagination jProjectSupervisePagination) { jProjectSupervisePagination.setDataType("1"); //无需分页 List<JProjectSuperviseEntity> list = jProjectSuperviseService.getList(jProjectSupervisePagination); //处理id字段转名称,若无需转或者为空可删除 List<HPGExportVO> listVO = JsonUtil.getJsonToList(list, HPGExportVO.class); for (HPGExportVO exportVO : listVO) { JTopicLibraryEntity jTopicLibraryEntity = jProjectSuperviseService.getJTopicLibrary(exportVO.getTopicId()); if (Objects.nonNull(jTopicLibraryEntity)) { exportVO.setTopicName(jTopicLibraryEntity.getTopicName()); exportVO.setUpdatedBy(generaterSwapUtil.userSelectValues(exportVO.getUpdatedBy())); } } ExportUtil.exportExcel(HPGExportVO.class, response, "任务后评估", "任务后评估", listVO); }3.常用注解// 导出字段注解,value为表头名,index为顺序,从0开始,如果不指定则按照字段顺序导出 @ExcelProperty(value = "任务编码",index = 0) // 无需导出 @ExcelIgnore4.前端导出方法 methods: { exportExcel() { let data = { ...this.listQuery, ...this.query, keyword: this.keyword, dataType: 0, menuId: this.menuId, moduleId: '426394122396395781', sourceType: '3' } downloadExcel('/api/szyd/JProjectSupervise/hpgExport', data, { fileName: '任务后评估导出' }) }, }5.前端导出工具// excel文件导出 export function downloadExcel(url, data = {}, options = {}) { const fileName = `${options.fileName || 'file'}-${getCurrentDateTime()}.xlsx` const hideNotify = options.hideNotify || false return new Promise((resolve, reject) => { !hideNotify && Notification({ title: "导出中", message: "正在导出一份电子表格", iconClass: "el-icon-loading", duration: 2000 }) request({ url, method: "post", data, responseType: "blob" }).then(file => { downloadFileByBlob(file, fileName) resolve(file) }).catch(err => { reject(err) }) }) } // Blob下载文件 export function downloadFileByBlob (content, filename) { let eleLink = document.createElement("a"); eleLink.download = filename; eleLink.style.display = "none"; let blob = new Blob([content]); eleLink.href = URL.createObjectURL(blob); document.body.appendChild(eleLink); eleLink.click(); document.body.removeChild(eleLink); }6.导出到本地或指定位置EasyExcel.write("D:\\Tencent Files\\处理分析结果.xlsx") .head(ExcelWriteData.class) .excelType(ExcelTypeEnum.XLSX).sheet("Sheet1").doWrite(readList);
2024年04月15日
71 阅读
0 评论
0 点赞
2024-01-25
Java使用poi-tl动态生成word和pdf
1.导入依赖,注意版本必须匹配详情参见官网 poi-tl官方文档<!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--导出word--> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.10.5</version> </dependency> <!--xpwf转pdf(根据word导出pdf)--> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId> <version>2.0.2</version> </dependency> <!--SpringEL表达式--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.3.18</version> </dependency> <!-- https://mvnrepository.com/artifact/io.github.draco1023/poi-tl-ext --> <!--富文本解析--> <dependency> <groupId>io.github.draco1023</groupId> <artifactId>poi-tl-ext</artifactId> <version>0.3.22</version> <exclusions> <exclusion> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> </exclusion> <exclusion> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </exclusion> </exclusions> </dependency>2.准备文件模板{{data.id}} {{data.sno}} {{data.name}} {{data.sex}} {{data.age}} {{data.createTime}} 图片解析 {{@data.img}} 富文本 {{data.content}} SpringEL表达式对时间格式化 {{data.createTime == null ? "" : new java.text.SimpleDateFormat('yyyy-MM-dd').format(data.createTime)}} 字符串集合遍历 {{?data.list}} {{=#this}} {{/data.list}} 复杂对象集合遍历和取值 {{?data.cityList}} {{id}} {{name}} {{/data.cityList}} 3.生成文件到本地@Test public void test() { Student entity = new Student(); entity.setId("1"); entity.setSno("1"); entity.setName("张三"); entity.setSex("男"); entity.setAge(25); entity.setCreateTime(new Date()); final ArrayList<String> strings = new ArrayList<>(); strings.add("str1"); strings.add("str2"); strings.add("str3"); entity.setList(strings); // Base64图片 String base64Str = "这里填写Base64编码的图片字符串,此处限于篇幅省略"; entity.setImg(Pictures.ofBase64(base64Str, PictureType.JPEG).size(96, 45).create()); // 网络图片 // entity.setImg("https://www.lxrao.com/myfile/cat.jpg"); // 富文本 entity.setContent("此处粘贴富文本,此处限于篇幅省略"); List<City> list = new ArrayList<>(); City city1 = new City(); city1.setId(1); city1.setName("BeiJing"+"\n"); list.add(city1); City city2 = new City(); city2.setId(1); city2.setName("ShangHai"); list.add(city2); entity.setCityList(list); try(InputStream inputStream = getClass().getResourceAsStream("/templates/test.docx")) { Assert.isTrue(Objects.nonNull(inputStream),"模板不存在!"); HashMap<String,Object> map = new HashMap<>(); map.put("data",entity); // 富文本解析 HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy(); Configure configure = Configure.builder().bind("data.content", htmlRenderPolicy).useSpringEL().build(); XWPFTemplate template = XWPFTemplate.compile(inputStream,configure).render(map); // 1.导出word文件 template.writeAndClose(new FileOutputStream("C:\\Users\\LiXiangrong\\Desktop\\test.docx")); // 2.导出pdf文件 PdfOptions options = PdfOptions.create(); FileOutputStream outPDF = new FileOutputStream("C:\\Users\\LiXiangrong\\Desktop\\test.pdf"); PdfConverter.getInstance().convert(template.getXWPFDocument(), outPDF, options); outPDF.close(); } catch (IOException e) { System.out.println(e.getMessage()); } }4.下载到web端package com.example.springbootdemo.utils; import com.deepoove.poi.XWPFTemplate; import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter; import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions; import org.springframework.util.Assert; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Objects; public class ExportUtil { private static final String WORD = ".docx"; private static final String PDF = ".pdf"; private static final String TYPE = "application/octet-stream"; public static void exportWordOrPDF(HttpServletResponse response,Object o,String tempName,String exportName,String fileType) { final String fileSuffix = "word".equals(fileType) ? WORD : PDF; // 赋值数据对象 HashMap<String,Object> map = new HashMap<>(); map.put("data",o); // 读取模板文件 InputStream inputStream = ExportUtil.class.getResourceAsStream("/templates/"+tempName); Assert.isTrue(Objects.nonNull(inputStream),"模板文件不存在!"); XWPFTemplate template = XWPFTemplate.compile(inputStream).render(map); // 生成文件 response.setContentType(TYPE); try { response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(exportName+fileSuffix, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try { OutputStream outputStream = response.getOutputStream(); if ("word".equals(fileType)) { template.writeAndClose(outputStream); } else { PdfOptions options = PdfOptions.create(); PdfConverter.getInstance().convert(template.getXWPFDocument(), outputStream, options); outputStream.close(); } } catch (IOException e) { throw new RuntimeException("导出异常!"); } } }5.控制层接口@GetMapping("/exportPDF") public void exportPDF(HttpServletResponse response) { Student entity = new Student(); entity.setId("1"); entity.setSno("1"); entity.setName("张三"); entity.setSex("男"); entity.setAge(25); ExportUtil.exportWordOrPDF(response,entity,"test.docx","导出pdf测试","pdf"); } @GetMapping("/exportWORD") public void exportWORD(HttpServletResponse response) { Student entity = new Student(); entity.setId("1"); entity.setSno("1"); entity.setName("张三"); entity.setSex("男"); entity.setAge(25); ExportUtil.exportWordOrPDF(response,entity,"test.docx","导出word测试","word"); }6.浏览器地址栏输入url测试7.前端下载方法<el-button type="primary" @click="downloadToWord" :loading="downloadLoading">下载</el-button>下载公共方法写在工具类中// Blob下载文件 export function downloadFileByBlob (content, filename) { let eleLink = document.createElement("a"); eleLink.download = filename; eleLink.style.display = "none"; let blob = new Blob([content]); eleLink.href = URL.createObjectURL(blob); document.body.appendChild(eleLink); eleLink.click(); document.body.removeChild(eleLink); }下载方法放在methods:{}中import { downloadFileByBlob } from '@/utils' // Loading downloadLoading: false, downloadToWord() { const { id } = this.topicsInfo this.downloadLoading = true request({ url: `/api/szyd/JTopicRequestMeeting/export`, method: 'get', responseType: "blob", data: { id, type: 'word', temp: this.curTemp, exportName: 'test' } }).then(file => { this.$message({ message: '文件下载成功', type: 'success' }) downloadFileByBlob(file, document.title + '.docx') }).finally(() => { this.downloadLoading = false }) },
2024年01月25日
121 阅读
26 评论
0 点赞
2024-01-12
由MybatisPlus配置类未生效引出的问题到SpringBoot复写Bean
1.在某微服务项目中,测试提出一个缺陷:在列表输入框选择条件,不点击查询而是点击翻页,点击后页面刷新,按照条件筛选出数据数量但不显示数据,其实,本质上就是分页查询的页号溢出问题。由于该项目使用的是MybatisPlus,要解决这个问题其实只要写一个MybatisPlus配置类,中设置一个属性即可。 2.但是发现这个配置类设置的这个属性值未生效,在启动类中获取bean发现这个属性依然是false,注释掉这个Bean后发现依然存在这个Bean,这时候就找到在该项目的jar包中已经存在这个Bean导致自己写的Bean未生效。 3.于是思路就是要重写这个Bean,可以实现Spring中的接口:Bean定义注册后置处理器BeanDefinitionRegistryPostProcessor。代码如下:MybatisPlusMyConfigpackage jnpf.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * MyBatisPlus配置 */ @Configuration public class MybatisPlusMyConfig { /** * @Author LiXiangrong * @Description 复写MybatisPlusInterceptor * @Date 2024/01/11 18:04:33 * @Return com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor **/ @Bean("mybatisPlusInterceptor1") public MybatisPlusInterceptor mybatisPlusInterceptor() { // 核心插件 MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加分页插件(如果配置多个插件,切记分页最后添加) PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL); // dbType(数据库类型) innerInterceptor.setOverflow(true); // 默认值:false。溢出总页数后是否进行处理。 interceptor.addInnerInterceptor(innerInterceptor); return interceptor; } }MyBeanDefinitionRegistryPostProcessorpackage jnpf.config; import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.stereotype.Component; /** * @Author LiXiangrong * @Description 自定义的Bean定义注册后置处理器 * @Date 2024/01/11 18:06:08 **/ @Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { String bean1 = "mybatisPlusInterceptor"; String bean2 = "mybatisPlusInterceptor1"; // 复写MybatisPlusInterceptor // 若jar包和程序都注册了mybatisPlusInterceptor,就将程序里的bd覆盖掉jar包里的bd(继续使用jar包里的beanName,防止jar包中其它bean指定依赖了这个beanName) if (registry.containsBeanDefinition(bean1) && registry.containsBeanDefinition(bean2)) { // 移除bean1,用bean2注册一个新的bean1,然后把bean2移除(复写了bean1) registry.removeBeanDefinition(bean1); registry.registerBeanDefinition(bean1, registry.getBeanDefinition(bean2)); registry.removeBeanDefinition(bean2); } } @Override public void postProcessBeanFactory(@NotNull ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { } }
2024年01月12日
45 阅读
0 评论
0 点赞
2024-01-03
AOP实现防止前端请求重复提交
1.防止重复提交注解package com.risesun.common.core.annotation; import java.lang.annotation.*; /** * @Author LiXiangrong * @Description 防止重复提交注解 * @Date 2023/04/03 9:04:15 **/ @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RepeatSubmit { /** * 防重复操作限时标记数值(存储redis限时标记数值) */ String value() default "value" ; /** * 防重复操作过期时间(借助redis实现限时控制) */ long expireSeconds() default 10; }2.AOP实现防止请求重复提交package com.risesun.business.aspect; import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.json.JSONUtil; import com.risesun.common.core.annotation.RepeatSubmit; import com.risesun.common.core.constant.TokenConstants; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @Author LiXiangrong * @Description AOP实现防止请求重复提交 * @Date 2023/04/03 8:41:04 **/ @Slf4j @Component @Aspect public class NoRepeatSubmitAspect { @Autowired private RedisTemplate redisTemplate; private final String SIGN = "submit duplication"; private final String PREFIX = "PREVENT_DUPLICATION_PREFIX:"; /** * @Author LiXiangrong * @Description 定义切点 * @Date 2023/04/03 8:53:11 * @Return void **/ @Pointcut("@annotation(com.risesun.common.core.annotation.RepeatSubmit)") public void preventDuplication() {} /** * @Author LiXiangrong * @Description 环绕方法 * @Date 2023/04/03 8:52:50 * @Param pjp * @Return java.lang.Object **/ @Around("NoRepeatSubmitAspect.preventDuplication()") public Object around(ProceedingJoinPoint pjp) throws Throwable { // 获取请求信息 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 获取执行方法 Method method = ((MethodSignature) pjp.getSignature()).getMethod(); //获取防重复提交注解 RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); // 获取authorization以及方法标记,生成redisKey和redisValue String authorization = request.getHeader(TokenConstants.AUTHENTICATION); String url = request.getRequestURI(); // 通过前缀 + url + token + 函数参数签名 来生成redis上的 key String redisKey = PREFIX.concat(url).concat(authorization).concat(getMethodSign(method, pjp.getArgs())); // 判断redisTemplate是否存在标记,如果没有,则是首次提交该请求,需要把设置标记并且正常返回 if (!redisTemplate.hasKey(redisKey) && Objects.nonNull(annotation)) { // 这个值只是为了标记,不重要 String redisValue = redisKey.concat(annotation.value()).concat(SIGN); // 设置防重复操作的限时标记(前置通知) redisTemplate.opsForValue().set(redisKey, redisValue, annotation.expireSeconds(), TimeUnit.SECONDS); try { // 正常执行方法并返回 ProceedingJoinPoint类型参数可以决定是否执行目标方法, // 环绕通知必须要有返回值,返回值即为目标方法的返回值 return pjp.proceed(); } catch (Throwable throwable) { //确保方法执行异常实时释放限时标记(异常后置通知) redisTemplate.delete(redisKey); throw throwable; } } else { throw new RuntimeException("数据正在处理,请勿重复提交!"); } } /** * @Author LiXiangrong * @Description 获取方法签名生成方法标记,采用数字签名算法SHA1对方法签名字符串加签 * @Date 2023/04/03 8:49:45 * @Param method * @Param args * @Return java.lang.String **/ private String getMethodSign(Method method, Object... args) { StringBuilder sb = new StringBuilder(method.toString()); for (Object arg : args) { sb.append(toString(arg)); } return DigestUtil.sha1Hex(sb.toString()); } /** * @Author LiXiangrong * @Description 对参数重写toString方法,避免空参造成的影响 * @Date 2023/04/03 8:50:58 * @Param arg * @Return java.lang.String **/ private String toString(Object arg) { if (Objects.isNull(arg)) { return "null"; } if (arg instanceof Number) { return arg.toString(); } return JSONUtil.toJsonStr(arg); } }
2024年01月03日
45 阅读
0 评论
0 点赞
1
2
3