这里写目录标题
- 前言
- 一、核心环境准备(必看!)
-
- [1.1 软件与依赖](#1.1 软件与依赖)
- [1.2 关键环境配置](#1.2 关键环境配置)
- [1.3 导入 NX 官方 Jar 包](#1.3 导入 NX 官方 Jar 包)
- 二、实现逻辑总览
- [三、完整实现代码(SpringBoot Service 层)](#三、完整实现代码(SpringBoot Service 层))
- 四、关键代码解析
-
- [4.1 NX 会话初始化](#4.1 NX 会话初始化)
- [4.2 参数读取核心](#4.2 参数读取核心)
- [4.3 参数修改核心](#4.3 参数修改核心)
- [4.4 STP 导出核心](#4.4 STP 导出核心)
- 五、常见问题与解决方案
- 总结
前言
在工业设计、智能制造场景中,经常需要通过Java 后端程序远程操控 Siemens NX(UG),实现模型参数自动化读取、批量修改、模型格式转换(导出 STP)等操作,替代人工手动处理,大幅提升效率。
本文基于 NX 11.0 版本,完整实现 Java 对接 NX 的核心功能:
NX 环境变量配置 + Jar 包加载
Java 远程打开 NX 模型文件
读取模型所有表达式参数
批量修改模型参数并保存
调用 NX 命令行工具导出 STP 214 文件
完整业务层代码(SpringBoot 环境)
全程可直接复制运行,适合二次开发!
一、核心环境准备(必看!)
1.1 软件与依赖
本地已安装 Siemens NX 11.0(必须完整安装,不能绿色版)
Java 开发环境:JDK 8+
框架:SpringBoot(普通 Java 项目也可使用)
1.2 关键环境配置
NX 二次开发必须配置系统环境变量,否则 Java 无法加载 NX 底层依赖,会直接报错:no libnxopen... in java.library.path
- 配置 PATH 环境变量
添加 NX 的二进制文件目录(根据自己安装路径修改):
plaintext
D:\Siemens\NX 11.0\UGII
D:\Siemens\NX 11.0\UGII\cpplibs - 配置 UGII_ROOT_DIR
plaintext
UGII_ROOT_DIR = D:\Siemens\NX 11.0\UGII\ - 配置 java.library.path(代码启动参数)
IDEA 启动配置中添加 JVM 参数:
plaintext
-Djava.library.path=D:\Siemens\NX 11.0\UGII
1.3 导入 NX 官方 Jar 包
从 NX 安装目录复制核心 Jar 到项目中(本地加载):
找到 NX 安装目录:NX 11.0\UGII\java
复制以下 Jar 到项目 lib 目录:
nxopen.jar
二、实现逻辑总览
整体流程非常清晰:
初始化 NX 会话:Java 连接 NX 后台进程
打开模型文件:加载 .prt 模型
读取参数:遍历模型表达式,封装为 Map 返回
修改参数:根据传入的键值对更新表达式,执行模型更新
导出 STP:调用 NX 自带的 step214ug.cmd 命令行工具,执行格式转换
关闭会话:释放 NX 资源,避免进程卡死
三、完整实现代码(SpringBoot Service 层)
核心功能说明
readModelParams:读取 NX 模型所有参数
writeModelParams:批量修改参数并保存模型
exportStp:导出 STP 文件并提供下载
封装工具方法:打开文件、关闭文件、参数转换、表达式修改
完整源码
配置环境变量



bash
package com.example.creotest2.demos.service.impl;
import com.example.creotest2.demos.DTO.FileDTO;
import com.example.creotest2.demos.service.SomNxService;
import com.example.creotest2.demos.utils.FileProcess;
import com.ptc.cipjava.jxthrowable;
import nxopen.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
/**
* Creo 参数 读写接口(对接前端专用)
* 接口1:读取模型参数 → 返回 Map<String,Object>
* 接口2:传入修改后的 Map → 更新模型并保存
*/
@Service
public class SomNxServiceImpl implements SomNxService {
private static boolean useSystemLookAndFeel = true;
private static Session theSession;
//读取nx模型参数
public Map<String, Object> readModelParams(String partName) throws Exception {
Map<String, Object> partParaMap = new HashMap<>();
try {
String prtFile = "E:\\willdelete\\creo\\creotest2\\creotest2\\"+partName+".prt";
Part part = openPartFile(prtFile);
ExpressionCollection expressions = part.expressions();
partParaMap = paramsToMap(expressions);
closePartFile(part);
return partParaMap;
}catch (Exception e){
e.printStackTrace();
return partParaMap;
}finally {
}
}
// 写参数
public FileDTO writeModelParams(String partName, Map<String, Object> map) throws jxthrowable, RemoteException, NXException {
FileDTO fileDTO = new FileDTO();
try {
//首先根据文件名找到对应的part文件,然后获取相关参数,根据传入的参数得key和value进行修改
String prtFile = "E:\\willdelete\\creo\\creotest2\\creotest2\\"+partName+".prt";
Part part = openPartFile(prtFile);
updateExpression(part,map);
theSession.updateManager().doUpdate(Update.Option._NOW);
part.save(BasePart.SaveComponents.TRUE,BasePart.CloseAfterSave.FALSE);
fileDTO.setFileName(partName);
closePartFile(part);
return fileDTO;
}catch (Exception e){
e.printStackTrace();
return fileDTO;
}finally {
}
}
//导出stp文件
public void exportStp(String partName,HttpServletResponse response) throws jxthrowable, RemoteException, NXException {
try {
String nxCmd = "D:\\Siemens\\NX 11.0\\STEP214UG\\step214ug.cmd";
String inputfile = "E:\\willdelete\\creo\\creotest2\\creotest2\\"+partName+".prt";
this.readModelParams(partName);
// String inputfile = "E:\\willdelete\\creo\\creotest2\\creotest2\\zhichengzuo1.prt";
String outFile = "E:\\willdelete\\creo\\creotest2\\creotest2\\"+partName+".step";
String defFile = "D:\\Siemens\\NX 11.0\\STEP214UG\\ugstep214.def";
String log = "E:\\willdelete\\creo\\creotest2\\creotest2"+partName+".log";
File wordDir = new File("D:\\Siemens\\NX 11.0\\STEP214UG");
String cmdLine = String.format("\"%s\" \"%s\" d=\"%s\" o=\"%s\" l=\"%s\" ",nxCmd,inputfile,defFile,outFile,log );
ProcessBuilder pb = new ProcessBuilder("cmd.exe","/c",cmdLine);
pb.directory(wordDir);
String command = String.join(" ",pb.command());
System.out.printf(command);
pb.redirectErrorStream(true);
Process process = pb.start();
try(BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "GBK"))){
String line;
while ((line = reader.readLine()) != null){
System.out.println(line);
}
}
int i = process.waitFor();
System.out.printf(String.valueOf(i));
File file = new File(outFile);
this.download(partName+".step",response);
if (file.exists()){
System.out.printf("生成成功"+file.getAbsolutePath());
}else {
System.out.printf(" 文件没生成");
}
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
} catch (UnsupportedEncodingException unsupportedEncodingException) {
unsupportedEncodingException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
closePartFile(null);
}
}
//将所有参数转换为map进行返回
private Map<String, Object> paramsToMap(ExpressionCollection expressions) throws jxthrowable, RemoteException, NXException {
TaggedObjectCollection.Iterator iterator = expressions.iterator();
Map<String, Object> map = new HashMap<>();
while ( iterator.hasNext()){
TaggedObject obj = (TaggedObject) iterator.next();
Expression exp = (Expression) obj;
String name = exp.name();
double val = exp.value();
map.put(name, val);
System.out.printf("参数名: %-20s | 数值 : %.3f \n ",exp.name(),exp.value());
}
// 核心:读取并返回 Map
return map;
}
//关闭文件
private void closePartFile (Part part){
if (part == null){
return;
}
try {
theSession.parts().closeAll(BasePart.CloseModified.CLOSE_MODIFIED,null);
} catch (RemoteException e) {
System.out.printf("所有零件已经关闭");
e.printStackTrace();
} catch (NXException e) {
System.out.printf("零件关闭失败");
e.printStackTrace();
}
}
//打印零件的所有表达式
private void printAllExpression(Part part) throws RemoteException, NXException {
System.out.printf("零件 所有表达式 \n");
ExpressionCollection expressions = part.expressions();
TaggedObjectCollection.Iterator iterator = expressions.iterator();
while ( iterator.hasNext()){
TaggedObject obj = (TaggedObject) iterator.next();
Expression exp = (Expression) obj;
System.out.printf("参数名: %-20s | 数值 : %.3f \n ",exp.name(),exp.value());
}
}
//修改零件的参数
private void updateExpression(Part part,Map<String,Object> paramMap) throws RemoteException, NXException {
ExpressionCollection expressionCollection = part.expressions();
TaggedObjectCollection.Iterator iterator = expressionCollection.iterator();
while (iterator.hasNext()){
TaggedObject obj = (TaggedObject) iterator.next();
Expression expression = (Expression) obj;
if (paramMap.containsKey(expression.name())){
Object value = paramMap.get(expression.name());
if (value instanceof Number){
double doubleValue = ((Number)value).doubleValue();
expression.setValue(doubleValue);
System.out.printf("参数 [%s] 已修改为 : %.3f%n",expression.name(),doubleValue);
}
}
}
}
public FileDTO upload(MultipartFile file) throws Exception{
FileProcess fileProcess = new FileProcess();
FileDTO upload = fileProcess.upload(file);
return upload;
}
public void download(String fileName, HttpServletResponse response) throws Exception {
FileProcess fileProcess = new FileProcess();
fileProcess.download(fileName,response);
}
//打印零件的基本信息 名称以及完整路径
private void printPartBasicInfo(Part part) throws NXException, RemoteException {
System.out.printf("零件的基本信息 \n");
System.out.printf("零件名称: %s%n",part.name() );
System.out.printf("完整路径: %s%n",part.fullPath());
}
//打开零件
private Part openPartFile(String filePath) throws RemoteException, NXException, MalformedURLException, NotBoundException {
System.out.printf("正在打开零件文件\n");
initNxSession();
PartCollection.OpenData open = theSession.parts().open(filePath);
Part part = open.part;
return part;
}
private void initNxSession() throws NXException, RemoteException, NotBoundException, MalformedURLException {
if ( System.getProperty("remoteserver") == null ) {
theSession = (Session) SessionFactory.get("Session");
}
else {
theSession = (Session) Naming.lookup(System.getProperty("remoteserver"));
}
System.out.printf("会话初始化成功 \n");
}
// public static void main(String[] args) throws RemoteException, NXException, MalformedURLException, NotBoundException {
//
// try {
//
//// System.out.println("java.lib.path:"+System.getProperty("java.library.path"));
// initNxSession();
// //打开指定的prt文件
//
// String prtFile = "E:\\willdelete\\creo\\creotest2\\creotest2\\zhichengzuo1.prt";
// Part part = openPartFile(prtFile);
// printPartBasicInfo(part);
////
//// //读取模型里边的参数
//// printAllExpression(part);
//// //修改参数
//// updateExpression(part,"底高",28.0);
//// theSession.updateManager().doUpdate(Update.Option._NOW);
////
//// //重新打印参数
//// printAllExpression(part);
//// //保存生成的零件
//// part.save(BasePart.SaveComponents.TRUE,BasePart.CloseAfterSave.FALSE);
//
//
//// exportStp();
//// exportIges();
//
// }catch (Exception e){
//
// e.printStackTrace();
// }finally {
// closePartFile(null);
// }
// }
}
四、关键代码解析
4.1 NX 会话初始化
java
运行
private void initNxSession() throws Exception {
if (System.getProperty("remoteserver") == null) {
// 本地连接 NX
theSession = (Session) SessionFactory.get("Session");
} else {
// 远程 RMI 连接
theSession = (Session) Naming.lookup(System.getProperty("remoteserver"));
}
}
支持本地调用和远程调用两种模式
会话全局单例,避免重复创建导致 NX 崩溃
4.2 参数读取核心
通过 ExpressionCollection 获取模型所有表达式,遍历封装为 Map,直接返回给前端使用。
4.3 参数修改核心
java
运行
// 修改参数值
exp.setValue(value);
// 必须执行模型更新,修改才会生效
theSession.updateManager().doUpdate(Update.Option._NOW);
// 保存模型
part.save();
4.4 STP 导出核心
使用 Java ProcessBuilder 调用 NX 官方命令行工具 step214ug.cmd,无需自己写导出逻辑,稳定不报错。
命令格式:
cmd
step214ug.cmd "输入文件.prt" d="配置文件.def" o="输出文件.stp" l="日志.log"
五、常见问题与解决方案
- 报错:java.library.path 找不到依赖
检查 PATH 环境变量是否添加 UGII 目录
检查 IDEA JVM 参数是否配置 -Djava.library.path - NX 进程卡死
每次操作后必须调用 closePartFile() 关闭模型
不要重复创建 Session 对象 - STP 导出失败
检查 step214ug.cmd 路径是否正确
模型文件路径不能包含中文、空格
确保 NX 有读写文件权限 - 参数修改不生效
忘记调用 doUpdate() 执行模型更新
参数名称不匹配(区分大小写)
六、总结
本文完整实现了 Java + NX 11.0 远程自动化操作,涵盖工业场景最常用的三大功能:
✅ 模型参数一键读取
✅ 批量参数修改与保存
✅ 标准 STP 文件导出
代码基于 SpringBoot 封装,可直接对接前端接口,也可用于自动化脚本、批量处理工具开发。
使用建议:
路径统一配置到 application.yml,不要硬编码
增加异常捕获和日志记录,方便生产环境排查
远程部署时,服务器必须安装 NX 并配置相同环境变量
需要配套的 FileProcess 工具类、DTO 类、前端调用示例的同学,可以评论区留言,我会继续更新!