Commit d06c9fb1 by zwb

添加简历html导出

parent 0cba9cea
...@@ -55,4 +55,19 @@ public interface CacheConstants { ...@@ -55,4 +55,19 @@ public interface CacheConstants {
/**个人简历redis缓存 推荐岗位用*/ /**个人简历redis缓存 推荐岗位用*/
String REDIS_USER_RESUME_RECOMMEND_KEY = "recommend_resume_data:%s"; String REDIS_USER_RESUME_RECOMMEND_KEY = "recommend_resume_data:%s";
/**
* 简历下载数据缓存
*/
String CREATE_RESUME_HTML = "create:resume:html:%s";
/**
* 简历下载数据缓存数据
*/
String CREATE_RESUME_HTML_DATA = "create:resume:html:data:%s";
/**
* 下载使用简历对应模版缓存
*/
String RESUME_TEMPLATE_ID = "template:resume:download:%s";
} }
package org.dromara.common.core.constant;
/**
* @author jiangxiaoge
*/
public interface SecurityConstants {
/**
* 启动时是否检查Inner注解安全性
*/
boolean INNER_CHECK = true;
/**
* 刷新
*/
String REFRESH_TOKEN = "refresh_token";
/**
* 验证码有效期
*/
int CODE_TIME = 60;
/**
* 验证码长度
*/
String CODE_SIZE = "4";
/**
* 角色前缀
*/
String ROLE = "ROLE_";
/**
* 前缀
*/
String PANGU_PREFIX = "pangu_";
/**
* token 相关前缀
*/
String TOKEN_PREFIX = "token:";
/**
* oauth 相关前缀
*/
String OAUTH_PREFIX = "oauth:";
/**
* 授权码模式code key 前缀
*/
String OAUTH_CODE_PREFIX = "oauth:code:";
/**
* 标志
*/
String HEADER_FROM = "JXG-From";
/**
* 内部
*/
String FROM_IN = "in";
/**
* 外部
*/
String FROM_OUT = "out";
/**
* gateway
*/
String FROM_GATEWAY = "gateway";
/**
* User
*/
String HEADER_PANGU_USER = "JXG-User";
/**
* OAUTH URL
*/
String OAUTH_TOKEN_URL = "/auth/user/login/sms";
/**
* OAUTH Check token URL
*/
String OAUTH_CHECK_TOKEN_URL = "/auth/get-verification-code";
/**
* OAUTH URL
*/
String OAUTH_CALLBACK_URL = "/auth/user/login/callback";
/**
* 移动端授权
*/
String GRANT_MOBILE = "mobile";
/**
* 用户类型
*/
String HEADER_USER_TYPE = "userType";
/**
* 前端用户
*/
String FRONT_USER = "FRONT_USER";
/**
* 后端用户
*/
String ADMIN_USER = "ADMIN";
/**
* QQ获取token
*/
String QQ_AUTHORIZATION_CODE_URL = "https://graph.qq.com/oauth2.0/token?grant_type="
+ "authorization_code&code=%S&client_id=%s&redirect_uri=" + "%s&client_secret=%s";
/**
* 微信获取OPENID
*/
String WX_AUTHORIZATION_CODE_URL = "https://api.weixin.qq.com/sns/oauth2/access_token"
+ "?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
/**
* 微信小程序OPENID
*/
String MINI_APP_AUTHORIZATION_CODE_URL = "https://api.weixin.qq.com/sns/jscode2session"
+ "?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
/**
* 码云获取token
*/
String GITEE_AUTHORIZATION_CODE_URL = "https://gitee.com/oauth/token?grant_type="
+ "authorization_code&code=%S&client_id=%s&redirect_uri=" + "%s&client_secret=%s";
/**
* 开源中国获取token
*/
String OSC_AUTHORIZATION_CODE_URL = "https://www.oschina.net/action/openapi/token";
/**
* QQ获取用户信息
*/
String QQ_USER_INFO_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";
/**
* 码云获取用户信息
*/
String GITEE_USER_INFO_URL = "https://gitee.com/api/v5/user?access_token=%s";
/**
* 开源中国用户信息
*/
String OSC_USER_INFO_URL = "https://www.oschina.net/action/openapi/user?access_token=%s&dataType=json";
/**
* 钉钉获取 token
*/
String DING_OLD_GET_TOKEN = "https://oapi.dingtalk.com/gettoken";
/**
* 钉钉同步部门列表
*/
String DING_OLD_DEPT_URL = "https://oapi.dingtalk.com/topapi/v2/department/listsub";
/**
* 钉钉部门用户id列表
*/
String DING_DEPT_USERIDS_URL = "https://oapi.dingtalk.com/topapi/user/listid";
/**
* 钉钉用户详情
*/
String DING_USER_INFO_URL = "https://oapi.dingtalk.com/topapi/v2/user/get";
/**
* {bcrypt} 加密的特征码
*/
String BCRYPT = "{bcrypt}";
/**
* 客户端模式
*/
String CLIENT_CREDENTIALS = "client_credentials";
/**
* 客户端编号
*/
String CLIENT_ID = "client_id";
/**
* 客户端唯一令牌
*/
String CLIENT_RECREATE = "recreate_flag";
/**
* 用户ID字段
*/
String DETAILS_USER_ID = "user_id";
/**
* 用户名
*/
String DETAILS_USERNAME = "username";
/**
* 姓名
*/
String NAME = "name";
/**
* 协议字段
*/
String DETAILS_LICENSE = "license";
/**
* 项目的license
*/
String PANGU_LICENSE = "made in pangu";
/**
* 项目的issue
*/
String PANGU_ISSUER = "https://spring.io";
/**
* 激活字段 兼容外围系统接入
*/
String ACTIVE = "active";
/**
* AES 加密
*/
String AES = "aes";
/**
* 授权码模式confirm
*/
String CUSTOM_CONSENT_PAGE_URI = "/token/confirm_access";
/**
* {noop} 加密的特征码
*/
String NOOP = "{noop}";
/**
* 短信登录 参数名称
*/
String SMS_PARAMETER_NAME = "mobile";
/**
* 手机号登录
*/
String APP = "mobile";
/**
* 用户信息
*/
String DETAILS_USER = "user_info";
String USERNAME = "username";
String PASSWORD = "password";
/**
* 密钥
*/
String PASS = "pangu123456pangu";
/**
* cas_login
*/
String CAS_LOGIN = "cas_login";
String COZE_REDIRECT_URI = "http://localhost:9999/auth/coze_token";
String COZE_ID = "73631854299105702028906918546848.app.coze";
String COZE_KEY = "gjrH6Hv5uxJFg4NhELxbNxzKxc2i8cptsVPzJiyiuyccIHmA";
/**
* 标志亲亲小宝登录使用
*/
String QQXB_FROM = "Qqxb-From";
/**
* 标志亲亲小宝登录使用
*/
String QQXB_OUT = "qqxb";
/**
* 标志亲亲小宝嵌入页面使用的登录存储token
*/
String AUTH_QQXB_TOKEN = "qqxb_token_html5:";
/**
* 就业小知第三方使用登录使用
*/
String JYXZ_OUT = "jyxz";
/**
* 项目一组
*/
String XMYZ_OUT = "xmyz";
/**
* 学校端
*/
String XXD_OUT = "xxd";
}
package com.bkty.system.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* @author jiangxiaoge
* <p>
* 网关通用配置文件
*/
@Data
@Component
@RefreshScope
@ConfigurationProperties("template")
public class AiConfigProperties {
/**
* 网关解密登录前端密码 秘钥
*/
public String path = "/resume/template/";
public String report = "/Users/wangwenjiang/Desktop/";
public String pdfDown = "https://xzt-dev.jinsehuaqin.com/pdf_down/";
public String htmlDown = "https://xzt-dev.jinsehuaqin.com/html_down/";
public String imagesDown = "https://xzt-dev.jinsehuaqin.com/images_down/";
public String avatarPath = "/resume/avatarImages/";
public String avatarImages = "https://xzt-dev.jinsehuaqin.com/avatar_images/";
public String pdfDownZs = "https://xzt-dev.jinsehuaqin.com/pdf_down_zs/";
public String htmlDownZs = "https://xzt-dev.jinsehuaqin.com/html_down_zs/";
public String imagesDownZs = "https://xzt-dev.jinsehuaqin.com/images_down_zs/";
public String avatarImagesZs = "https://xzt-dev.jinsehuaqin.com/avatar_images_zs/";
}
package com.bkty.system.controller; package com.bkty.system.controller;
import com.bkty.system.domain.dto.ResumeByPdfDto;
import com.bkty.system.domain.dto.ResumeListItemCache; import com.bkty.system.domain.dto.ResumeListItemCache;
import com.bkty.system.domain.dto.ResumeMakeDto; import com.bkty.system.domain.dto.ResumeMakeDto;
import com.bkty.system.domain.entity.FunctionResumeDownloadNumber;
import com.bkty.system.domain.vo.ResumeByPdfVo;
import com.bkty.system.domain.vo.ResumeVo; import com.bkty.system.domain.vo.ResumeVo;
import com.bkty.system.service.resume.NewEditionResumeService; import com.bkty.system.service.resume.NewEditionResumeService;
import com.bkty.system.service.resume.ResumeCacheService; import com.bkty.system.service.resume.ResumeCacheService;
...@@ -91,12 +94,16 @@ public class NewEditionResumeController { ...@@ -91,12 +94,16 @@ public class NewEditionResumeController {
/** /**
* 查询简历列表 * 查询简历列表
* @param request * @param
* @return * @return
*/ */
@PostMapping("/resumeList") @PostMapping("/resumeList")
public R<List<ResumeListItemCache>> resumeList(@RequestBody Map<String, Long> request){ public R<List<ResumeListItemCache>> resumeList(){
Long userId = request.get("userId"); UserLoginInfo userLoginInfo = SecurityUtils.getUser();
Long userId = 1L;
if (null != userLoginInfo){
userId = userLoginInfo.getId();
}
List<ResumeListItemCache> result = this.newEditionResumeService.resumeList(userId); List<ResumeListItemCache> result = this.newEditionResumeService.resumeList(userId);
return new R<>(result); return new R<>(result);
} }
...@@ -119,7 +126,18 @@ public class NewEditionResumeController { ...@@ -119,7 +126,18 @@ public class NewEditionResumeController {
userId = userLoginInfo.getId(); userId = userLoginInfo.getId();
} }
this.resumeCacheService.delResumeCache(Long.valueOf(dto.getResumeId()), userId); this.resumeCacheService.delResumeCache(Long.valueOf(dto.getResumeId()), userId);
return new R<>(); return R.ok();
}
/**
* 根据模版生成html文件
* @param dto
* @return
*/
@PostMapping("/create-resume-by-html")
public R createResumeHtml(@RequestBody ResumeByPdfDto dto){
return new R<>(this.newEditionResumeService.createResumeHtml(dto.getResumeId()));
} }
} }
package com.bkty.system.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "根据模版生成pdf,html,png文件请求类")
public class ResumeByPdfDto {
@Schema(description = "简历ID")
private String resumeId;
@Schema(description = "模版名称")
private String templateName;
@Schema(description = "权益id")
private String vipId;
}
package com.bkty.system.service.resume; package com.bkty.system.service.resume;
import com.bkty.system.domain.dto.ResumeByPdfDto;
import com.bkty.system.domain.dto.ResumeListItemCache; import com.bkty.system.domain.dto.ResumeListItemCache;
import com.bkty.system.domain.dto.ResumeMakeDto; import com.bkty.system.domain.dto.ResumeMakeDto;
import com.bkty.system.domain.vo.ResumeByPdfVo;
import com.bkty.system.domain.vo.ResumeVo; import com.bkty.system.domain.vo.ResumeVo;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
...@@ -60,4 +62,11 @@ public interface NewEditionResumeService { ...@@ -60,4 +62,11 @@ public interface NewEditionResumeService {
* @param dto * @param dto
*/ */
void delResume(ResumeMakeDto dto) ; void delResume(ResumeMakeDto dto) ;
/**
* 根据模版生成html文件
* @param resumeId
* @return
*/
String createResumeHtml(String resumeId);
} }
package com.bkty.system.service.resume; package com.bkty.system.service.resume;
import com.bkty.system.domain.dto.ResumeByPdfDto;
import com.bkty.system.domain.dto.ResumeListItemCache; import com.bkty.system.domain.dto.ResumeListItemCache;
import com.bkty.system.domain.dto.ResumeMakeDto; import com.bkty.system.domain.dto.ResumeMakeDto;
import com.bkty.system.domain.dto.ResumeModelOptimizationCache; import com.bkty.system.domain.dto.ResumeModelOptimizationCache;
...@@ -8,6 +9,7 @@ import com.bkty.system.domain.entity.FunctionResumeBase; ...@@ -8,6 +9,7 @@ import com.bkty.system.domain.entity.FunctionResumeBase;
import com.bkty.system.domain.entity.FunctionResumeModel; import com.bkty.system.domain.entity.FunctionResumeModel;
import com.bkty.system.domain.entity.FunctionResumeModelOptimization; import com.bkty.system.domain.entity.FunctionResumeModelOptimization;
import com.bkty.system.domain.vo.ResumeBaseVo; import com.bkty.system.domain.vo.ResumeBaseVo;
import com.bkty.system.domain.vo.ResumeByPdfVo;
import com.bkty.system.domain.vo.ResumeModelVo; import com.bkty.system.domain.vo.ResumeModelVo;
import java.util.List; import java.util.List;
...@@ -121,5 +123,10 @@ public interface ResumeCacheService { ...@@ -121,5 +123,10 @@ public interface ResumeCacheService {
*/ */
void saveResumeTemplateCache(Map<String,Object> templateMap, String resumeId); void saveResumeTemplateCache(Map<String,Object> templateMap, String resumeId);
/**
* 删除简历缓存
* @param userId
*/
void delResumeListCache(Long userId); void delResumeListCache(Long userId);
} }
...@@ -2,6 +2,7 @@ package com.bkty.system.service.resume.impl; ...@@ -2,6 +2,7 @@ package com.bkty.system.service.resume.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
...@@ -9,7 +10,9 @@ import com.alibaba.fastjson2.JSONObject; ...@@ -9,7 +10,9 @@ import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference; import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bkty.system.config.AiConfigProperties;
import com.bkty.system.config.CommonAsyncThreadPool; import com.bkty.system.config.CommonAsyncThreadPool;
import com.bkty.system.domain.dto.ResumeByPdfDto;
import com.bkty.system.domain.dto.ResumeListItemCache; import com.bkty.system.domain.dto.ResumeListItemCache;
import com.bkty.system.domain.dto.ResumeMakeDto; import com.bkty.system.domain.dto.ResumeMakeDto;
import com.bkty.system.domain.entity.*; import com.bkty.system.domain.entity.*;
...@@ -19,18 +22,21 @@ import com.bkty.system.service.comm.CommService; ...@@ -19,18 +22,21 @@ import com.bkty.system.service.comm.CommService;
import com.bkty.system.service.coze.CozeApiService; import com.bkty.system.service.coze.CozeApiService;
import com.bkty.system.service.resume.NewEditionResumeService; import com.bkty.system.service.resume.NewEditionResumeService;
import com.bkty.system.service.resume.ResumeCacheService; import com.bkty.system.service.resume.ResumeCacheService;
import com.bkty.system.utils.FileProcessor;
import com.bkty.system.utils.NewEditionResumeUtil; import com.bkty.system.utils.NewEditionResumeUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.CozeConstsnts; import org.dromara.common.core.constant.CozeConstsnts;
import org.dromara.common.core.constant.SecurityConstants;
import org.dromara.common.core.domain.UserLoginInfo; import org.dromara.common.core.domain.UserLoginInfo;
import org.dromara.common.core.enums.ResumeEnum; import org.dromara.common.core.enums.ResumeEnum;
import org.dromara.common.core.exception.WarnException; import org.dromara.common.core.exception.WarnException;
import org.dromara.common.core.utils.SecurityUtils; import org.dromara.common.core.utils.SecurityUtils;
import org.dromara.common.core.utils.SnowFlakeUtil; import org.dromara.common.core.utils.SnowFlakeUtil;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.WebUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
...@@ -39,6 +45,9 @@ import org.springframework.scheduling.annotation.Async; ...@@ -39,6 +45,9 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -92,6 +101,8 @@ public class NewEditionResumeServiceImpl implements NewEditionResumeService { ...@@ -92,6 +101,8 @@ public class NewEditionResumeServiceImpl implements NewEditionResumeService {
private final FunctionResumeBaseOptimizationMapper resumeBaseOptimizationMapper; private final FunctionResumeBaseOptimizationMapper resumeBaseOptimizationMapper;
private final AiConfigProperties properties;
@Override @Override
public void insertNewEditionResume(MultipartFile file, String type){ public void insertNewEditionResume(MultipartFile file, String type){
...@@ -632,7 +643,7 @@ public class NewEditionResumeServiceImpl implements NewEditionResumeService { ...@@ -632,7 +643,7 @@ public class NewEditionResumeServiceImpl implements NewEditionResumeService {
} }
//缓存简历大JSON //缓存简历大JSON
queryNewEditionResumeId(resumeMakeDto.getResumeId()); queryNewEditionResumeId(resumeMakeDto.getResumeId());
return resumeMakeDto.getResumeId(); return createResumeHtml(resumeMakeDto.getResumeId());
} }
@Override @Override
...@@ -666,4 +677,86 @@ public class NewEditionResumeServiceImpl implements NewEditionResumeService { ...@@ -666,4 +677,86 @@ public class NewEditionResumeServiceImpl implements NewEditionResumeService {
//this.resumeCacheService.refreshResumeListCache(this.baseMapper.queryResumeListV2(userId), userId); //this.resumeCacheService.refreshResumeListCache(this.baseMapper.queryResumeListV2(userId), userId);
this.resumeCacheService.delResumeListCache(userId); this.resumeCacheService.delResumeListCache(userId);
} }
@Override
public String createResumeHtml(String resumeId) {
if (StringUtils.isBlank(resumeId)){
throw new WarnException("简历ID不能为空");
}
ResumeByPdfVo vo = new ResumeByPdfVo();
/**是否展示0.显示 1.不显示*/
Map<String, Object> objectMap = newEditionResumeUtil.queryAllModelData(resumeId, "0");
Object baseInfo = objectMap.get("base");
if (baseInfo != null) {
JSONObject jsonObject = (JSONObject) JSON.toJSON(baseInfo);
String age = jsonObject.getString("birthday");
// 计算年龄
String calculatedAge = calculationAge(age);
// 放回 JSON 对象中
jsonObject.put("birthday", calculatedAge);
jsonObject.put("workTime", "");
// 更新 base_info
objectMap.put("base", jsonObject);
}
String jsonString = JSON.toJSONString(objectMap);
if(objectMap.get("base") != null){
Map<String, Object> map = JSON.parseObject(String.valueOf(objectMap.get("base")), Map.class);
if(map.get("resumeName") != null){
vo.setResumeName(map != null ? String.valueOf(map.get("resumeName")) : "");
}else {
FunctionResumeBase resumeBase = this.functionResumeBaseMapper.selectById(resumeId);
vo.setResumeName(resumeBase.getResumeName());
this.resumeCacheService.saveResumeModelDataCache(Long.valueOf(resumeId), Long.valueOf(resumeId), JSON.toJSONString(resumeBase));
}
vo.setUserName(map != null ? String.valueOf(map.get("username")) : "");
}
String data = redisTemplate.opsForValue().get(CacheConstants.CREATE_RESUME_HTML_DATA.formatted(resumeId));
if (StringUtils.isNotBlank(data)){
if(jsonString.equals(data)){
String json = redisTemplate.opsForValue().get(CacheConstants.CREATE_RESUME_HTML.formatted(resumeId));
if(StringUtils.isNotBlank(json)){
return json;
}
}
}
log.info("简历预览数据: {}", jsonString);
String htmlName = resumeId + ".html";
FileProcessor.processFile(properties.getPath() + "template/" + "templateName", properties.getPath() + "output/" + htmlName, "<%- data %>", jsonString);
redisTemplate.opsForValue().set(CacheConstants.CREATE_RESUME_HTML_DATA.formatted(resumeId), jsonString);
redisTemplate.opsForValue().set(CacheConstants.CREATE_RESUME_HTML.formatted(resumeId), properties.getHtmlDown() + htmlName);
return properties.getHtmlDown() + htmlName;
}
/**
* 根据生日计算年龄
*/
public String calculationAge(String birthStr) {
if (birthStr == null || birthStr.isEmpty()) return "";
LocalDate birthDate = null;
try {
if (birthStr.length() == 7) { // 格式:yyyy-MM
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
birthDate = LocalDate.parse(birthStr, formatter).withDayOfMonth(1);
} else if (birthStr.length() == 10) { // 格式:yyyy-MM-dd
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
birthDate = LocalDate.parse(birthStr, formatter);
} else {
return ""; // 不支持的格式
}
// 当前时间
LocalDate now = LocalDate.now(); // 或指定为 LocalDate.of(2025, 6, 1)
long years = ChronoUnit.YEARS.between(birthDate, now);
return String.valueOf(years);
} catch (Exception e) {
// 解析失败
return "";
}
}
} }
\ No newline at end of file
package com.bkty.system.utils;
import org.dromara.common.core.utils.DateTimeWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class FileProcessor {
/**
* 读取服务器路径上的文件,替换字符串并生成HTML文件
* @param sourceFilePath 原文件路径
* @param targetFilePath 目标HTML文件路径
* @param oldText 要替换的旧字符串
* @param newText 替换后的新字符串
*/
public static void processFile(String sourceFilePath, String targetFilePath, String oldText, String newText) {
File sourceFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
// 读取和替换逻辑
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), StandardCharsets.UTF_8));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
// 替换字符串
String replacedLine = line.replace(oldText, newText);
writer.write(replacedLine);
writer.newLine(); // 写入换行符
}
System.out.println("文件处理完成,已生成新的HTML文件:" + targetFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 示例:读取 `/data/test.txt`,将 `Hello` 替换为 `Hi`,生成 `/data/result.html`
/*String sourcePath = "/Users/wangwenjiang/Desktop/tpl2.ejs";
String targetPath = "/Users/wangwenjiang/Desktop/result.html";
String oldText = "Hello";
String newText = "Hi";
processFile(sourcePath, targetPath, oldText, newText);*/
// System.out.println(DateTimeWrapper.isWithinThisWeek(DateTimeWrapper.parse("2025-04-14 00:00:00")));
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment