java 转 exe, 带 jre 运行

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

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 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8216 回帖

相关帖子

欢迎来到这里!

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

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

    2 回复
  • alanfans
    作者

    最近没时间

  • mainlove

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

    1 回复
  • alanfans
    作者

    已更新

  • alanfans
    作者

    已更新

    1 回复
  • 88250

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

    1 回复
  • alanfans
    作者

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

    1 回复
  • 88250

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

    1 回复
  • alanfans via Android
    作者

    @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 回复
  • 好的,那我也这样算了

请输入回帖内容 ...