也是第一次尝试,查了很多资料,先检查自己的python环境(cmd:where python)是否有多个,否则调用python会报wait for =9009(1是执行失败0是成功)错误,其次最好安装conda(有命令界面,可直接使用pip命令,也是第一次使用,感兴趣或者深度学习的可以具体看看)来管理python的包,尤其是发布到服务器Linux,用conda方便一些,就不用再去安装环境以及第三方的包,自带python环境,不过注意一下对应python的版本,否则会有一些包版本高导致的问题(如Cryptography版本问题,需卸载后安装低版本),很多包的引用会出现问题,可以升级conda的python的版本,也可以降低第三方包的版本。演示本地环境win下的效果,linux下需要根据实际情况去调试。
1、这是自己测试的时候放python代码以及需要执行的文件地方,可根据需要处理(这里处理的业务是读取接口传pdf文件为csv格式,再对csv文件进行各种处理再到java中回调,涉及调用多个python脚本)
java代码,传递到python的参数可以在ProcessBuilder中加,我这里就传递了一个文件过去。还有其他的一些其他方法比如jpython包这些,不过随着版本的跟新大多跟不上了,很多支持不了,包也没维护了。
File resourceDir = new File("framework-web/src/main/resources/py");
String windowsPath = resourceDir.getAbsolutePath();
String fileName1 = windowsPath + "/1pdf.py";
String pdf_path1 = windowsPath + "/ylz.pdf";
String fileName2 = windowsPath + "/2pdf_csv.py";
String pdf_path2 = windowsPath + "/pdf.csv";
//多次调用生成新的文件再进行调用,所以用简单的线程保证逐一执行
Thread thread1 = new Thread(()->{
try{
pdf(fileName1,pdf_path1);
}catch (Exception e){
e.printStackTrace();
}
});
Thread thread2 = new Thread(()->{
try{
pdf(fileName2,pdf_path2);
}catch (Exception e){
e.printStackTrace();
}
});
thread1.start();
thread1.join();//等待线程一执行完毕再执行线程二
thread2.start();
thread2.join();
//调用方法
private static void pdf(String fileName,String pdf_path){
String os = System.getProperty("os.name");
String linuxPath = "/ai/egcc/";//TODO 需要根据实际情况修改
ProcessBuilder processBuilder;
if (os.startsWith("Windows")){
// windows执行脚本也可以使用 cmd.exe /c 才能正确执行脚本,我这里指定的conda
processBuilder = new ProcessBuilder("D:\\CodeSoft\\Anaconda3\\python.exe", fileName, pdf_path);
}else {
// linux执行脚本一般是使用python3 + 文件所在路径
processBuilder = new ProcessBuilder("python3", linuxPath + fileName, pdf_path);
}
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
// 读取Python脚本的输出
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待Python脚本执行完成
int exitCode = process.waitFor();
if (exitCode != 0) {
System.out.println("Python 脚本错误: " + exitCode);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
python代码 ,这里是简单的pdf读取转为csv文件的方法。
import pdfplumber # pip安装
import pandas as pd
import re
import sys
# 创建一个空的DataFrame
def fun(pdf_path):
df = pd.DataFrame(columns=['Content', 'FontName', 'FontSize', 'LeftIndent', 'Width', 'Height'])
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
for text_line in page.extract_text_lines():
if text_line:
# 获取文本内容
content = text_line['text']
# 跳过不包含文字的部分
if re.search(r'[\u4e00-\u9fff]', content):
# 获取字体名称
fontname = text_line['chars'][0].get('fontname', 'N/A') # 如果不存在,使用'N/A'
# 获取字体大小
fontsize = text_line['chars'][0].get('size', 'N/A')
# 获取左缩进
x0 = text_line['chars'][0].get('x0', 'N/A')
# 获取字体宽和高
height = text_line['chars'][0].get('height', 'N/A')
width = text_line['chars'][0].get('width', 'N/A')
# 将数据添加到DataFrame
df = df.append(
{'Content': content, 'FontName': fontname, 'FontSize': fontsize, 'LeftIndent': x0,
'Width': width, 'Height': height},
ignore_index=True)
# 保存DataFrame为CSV文件
csv_path = 'framework-web/src/main/resources/py/pdf.csv'
df.to_csv(csv_path, index=False, encoding='utf_8_sig')
# print(f'CSV文件已保存到: {csv_path}')
if __name__ == '__main__':
# 获取参数,执行python函数
pdf_path = sys.argv[1]
fun(pdf_path)
其他脚本一样的,就不贴了,就是把生成的文件再次传递到另外的脚本执行,这里会用到很多第三方的库,可根据需要安装对应的版本,跟在python环境区别还是有的,比如出现中文文件名等问题,需要对代码进行简单修改,可根据调用的报错查询,idea控制台打印的错误也跟pycharm执行的输出一样,可根据错误进行改造,根据实际情况调试就好。