java 转 exe, 带 jre 运行

本贴最后更新于 2034 天前,其中的信息可能已经时移俗易

exe4j 下载地址:http://www.ej-technologies.com/download/exe4j/files.php
需要注意的是 exe4j 6.0 需要的 jdk 版本为 1.8 及以上。
imagepng

安装完成运行软件,点击 Enter License。

imagepng

2png
用户名和公司随便填写即可。注册码下面的随便随便复制一个即可。

A-XVK258563F-1p4lv7mg7sav

A-XVK209982F-1y0i3h4ywx2h1

A-XVK267351F-dpurrhnyarva

A-XVK204432F-1kkoilo1jy2h3r

A-XVK246130F-1l7msieqiwqnq

A-XVK249554F-pllh351kcke50

A-XVK238729F-25yn13iea25i

A-XVK222711F-134h5ta8yxbm0

A-XVK275016F-15wjjcbn4tpj

A-XVK275016F-15wjjcbn4tpj 

然后点击 ok 即可完成激活。

写 java 客户端

jdk8
JavaFX FlowPane 布局(只是简单功能,选文件,对表格文件进行处理,写出新表格)
poi, easyexcel,commons
jre(1.8 32 位),我电脑是 64 位 jre,有报错,32 位的 jre 是从同事电脑上复制来的。

imagepng

package application;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;

public class ExcelPropertyIndexModel extends BaseRowModel{
	@ExcelProperty(value = "表头",index = 0)
	private String title;
	@ExcelProperty(value = "总合",index = 1)
	private Integer sum;
	

	public String getTitle() {
		return title;
	}


	public void setTitle(String title) {
		this.title = title;
	}


	public Integer getSum() {
		return sum;
	}


	public void setSum(Integer sum) {
		this.sum = sum;
	}


	public ExcelPropertyIndexModel(String title, Integer sum) {
		super();
		this.title = title;
		this.sum = sum;
	}


	public ExcelPropertyIndexModel() {
		super();
		// TODO Auto-generated constructor stub
	}


	

}

package application;
	
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			FlowPane root = (FlowPane)FXMLLoader.load(getClass().getResource("Sample.fxml"));
			Scene scene = new Scene(root,400,400);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}



package application;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.read.context.AnalysisContext;
import com.alibaba.excel.read.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;
import javafx.stage.FileChooser;

public class SampleController {
	
	@FXML
	private Button btnHello;
	@FXML
	private AnchorPane layoutpane;
	@FXML
	private TextArea filecontent;
	 

	 
	 //这里的handleButtonAction方法为我们在FXML文件中声明的onAction的处理函数
	    @FXML
	    protected void handleButtonAction(ActionEvent event) throws Exception {
	    	
	        
	        //打开文件选择器
	        FileChooser filechooser = new FileChooser();
	        filechooser.setTitle("请选择一个文件");
	        filechooser.setInitialDirectory(new File(System.getProperty("user.home")));
	        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("xlsx Files (*.xlsx)", "*.xlsx");
	        filechooser.getExtensionFilters().add(extFilter);
	        File selectedFile = filechooser.showOpenDialog(null);
	        
	        if (selectedFile != null) {
	        	Map<String,Object> map = readXLS(selectedFile.getAbsolutePath());
	        	List<String> list = (List<String>) map.get("1-1");
	        	Integer _sum = 0;
	        	for(String _a : list) {
	        		if(null != _a) {
	        			_sum += Integer.parseInt(_a);
	        		}
	        	}
	        	List<String> list0 = (List<String>) map.get("1-0");
	        	String title = "";
	        	for(String _t : list0) {
	        		if(null != _t) {
	        			title += _t + ",";
	        		}
	        	}
	        	//选一个目录
	        	FileChooser fileChooser1 = new FileChooser();
	        	fileChooser1.setTitle("保存文件");
	        	fileChooser1.getExtensionFilters().add(extFilter);
	        	fileChooser1.setInitialDirectory(new File(System.getProperty("user.home")));
	        	File file = fileChooser1.showSaveDialog(null);
	        	saveFile(file.getAbsolutePath(),title.substring(0, title.length() -1),_sum);
	        	btnHello.setText("File selected: " + selectedFile.getName());
	        }else {
	        	btnHello.setText("File selection cancelled.");
	        }

	    }
	
	    
	    //读xls
	    private Map<String,Object> readXLS(String fileName) throws FileNotFoundException{
	    	Map<String,Object> map = new HashMap<>();
	    	InputStream inputStream = new FileInputStream(fileName);
	    	try {
	    		ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null,
	                    new AnalysisEventListener<List<String>>() {
	                        @Override
	                        public void invoke(List<String> object, AnalysisContext context) {
	                        	//String _key = "当前sheet:" + context.getCurrentSheet().getSheetNo() + " 当前行:" + context.getCurrentRowNum();
	                        	String _key = context.getCurrentSheet().getSheetNo() + "-" + context.getCurrentRowNum();
	                            System.out.println(_key+" data:" + object);
	                            map.put(_key, object);
	                        }
	                            @Override
	                            public void doAfterAllAnalysed(AnalysisContext context) {

	                            }
	                        });
	                    reader.read();
	        }catch (Exception e){
	        }finally {
	            try {
	                inputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
			return map;
	    }
	    
	    //写xls
	    private void saveFile(String pathOfFileName,String title,Integer sum) throws FileNotFoundException {
	    	OutputStream  out = new FileOutputStream(pathOfFileName);
	    	try {
	            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
	            //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
	            Sheet sheet1 = new Sheet(1, 0,ExcelPropertyIndexModel.class);
	            ExcelPropertyIndexModel epim = new ExcelPropertyIndexModel(title,sum);
	            List<ExcelPropertyIndexModel> el = new ArrayList<ExcelPropertyIndexModel>();
	            el.add(epim);
	            writer.write(el, sheet1);
	            writer.finish();
	        } catch (Exception e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                out.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    	
}

导出可运行文件

imagepng

生成下面这样的文件

imagepng

下面就开始 jar 转 exe

打开 exe4j
我 win10 jdk8 忽略没问题,不用管
imagepng

首页

imagepng

下一步

imagepng

选 jar in exe mode,下一步

imagepng

写好名字,选好输出目录,下一步

imagepng

勾选单应用,下一步

exe4jgif

上面 gif 很清楚,加入 jar 和外面引用的库类 jar,指定 main 方法,下一步

imagepng

选好 jdk 版本,进入 search sequence

imagepng

删除之前原有的设置,只设置一个 .\jre,下一步

imagepng

下一步,下一步,最后

imagepng

1.8 的 32 位 jre 放进去

imagepng

endgif

==========================end==========================

只是做了表格处理,只是一个 demo,有问题可以留言

参考资料:

https://blog.csdn.net/qq_25189723/article/details/80052389
https://www.yiibai.com/javafx/javafx_filechooser.html#
https://github.com/alibaba/easyexcel/blob/master/quickstart.md
https://examples.javacodegeeks.com/desktop-java/javafx/javafx-filechooser-example/

  • exe4j
    1 引用 • 23 回帖
  • jar
    23 引用 • 121 回帖
  • exe
    4 引用 • 32 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3165 引用 • 8206 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • yaokwok

    2 回复
  • alanfans
    作者

    最近没时间

  • mainlove

    哈哈哈哈 我刚刚整好这个东西

    1 回复
  • alanfans
    作者

    已更新

  • alanfans
    作者

    已更新

    1 回复
  • 88250

    这样类似通知的场景可以使用“艾特参与者”功能 😉

    1 回复
  • alanfans
    作者

    艾特参与者 这个功能在哪?

    1 回复
  • 88250

    回帖的时候打艾特符合,自动完成列表里。

    1 回复
  • alanfans
    作者

    @88250 这个和回复差不多

  • 如果是前后端分离的项目,打包 exe ,前端要怎么处理?可以把 NGINX 也打包进去吗?

    1 回复
  • alanfans
    作者

    都分开了,你把前端打进来干啥,你干嘛不把数据库打包进来。

    1 回复
  • 打包进来为了方便 傻瓜化部署啊, 完全不懂技术的人,你叫他去装 NGINX,配置比较难,我数据库用 h2 。也算是打包进来了。

    2 回复
  • alanfans
    作者

    你自己写 bat 呗,java 还是可以运行 cmd 的,bat 运行你目录下的 nginx。

  • alanfans
    作者

    我理解的是这个 exe4j 打包了程序,运行时加载配置好的 jre 目录。jre 并没有打包,相当于外置了。

    1 回复
  • 我觉得也是,我不是想着如果全部打包进去,就一个文件,简介一点嘛。实在不行我就后端渲染了。 @88250 pipe 是怎么 处理前端的?我看到 解压的目录也没有 NGINX 啊。

    2 回复
  • alanfans
    作者

    这文章打包 jre 并没有打包进去

    1 回复
  • 我大概明白了

  • 88250

    你是前后端分离,然后现在前端需要一个 HTTP 服务?

    1 回复
  • 对的!

    1 回复
  • 88250

    前端资源编译打包好,用容器的 HTTP 服务就行了。

    1 回复
  • 我可以这么理解吗—— 假设我用的 springboot ,我前端编译好,然后 把编译 后的 index 作为 springboot 的 index 来用吗?

    1 回复
  • 88250 1

    是的,Pipe 就是这样实现的。

    1 回复
  • 好的,那我也这样算了

请输入回帖内容 ...