我通过 Peoplecode 使用 Apache POI 类 SXSSFWorkbook 将大量数据写入 Excel 文件。我对 Java 知之甚少,但能够通过 Peoplecode 使用 java 反射来组合生成文件的代码。不幸的是,Peoplecode 中存在一个错误,即使方法未重载,也必须使用反射。
例如,执行以下java代码:
SXSSFWorkbook workbook = new SXSSFWorkbook(100); /* 100 rows of accessible data */
SXSSFSheet sheet = workbook.getSheet(&name);
Peoplecode 中使用 java 反射的等效项是:
&_workbook = CreateJavaObject("org.apache.poi.xssf.streaming.SXSSFWorkbook", 100);
&_sheet = GetJavaClass("org.apache.poi.xssf.streaming.SXSSFSheet");
Local JavaObject &javaString = CreateJavaObject("java.lang.String", &name);
Local JavaObject &stringType = CreateJavaObject("java.lang.Class[]", &javaString.getClass());
Local JavaObject &getSheet = &_class.getDeclaredMethod("getSheet", &stringType);
Local JavaObject &args = CreateJavaObject("java.lang.Object[]", &javaString);
&_sheet = &getSheet.invoke(&_workbook, &args);
此技术适用于所有使用 String、Integer、boolean 作为参数值的方法。
现在我需要使用枚举常量“Never”禁用 Zip64 扩展。
所需的java代码:
workbook.setZip64Mode(Zip64Mode.Never);
更新: 我尝试了以下
&_workbook = CreateJavaObject("org.apache.poi.xssf.streaming.SXSSFWorkbook");
&_class = &_workbook.getClass();
Local JavaObject &javaString = GetJavaClass("org.apache.commons.compress.archivers.zip.Zip64Mode").valueOf("Never");
Local JavaObject &stringType = CreateJavaObject("java.lang.Class[]", GetJavaClass("org.apache.commons.compress.archivers.zip.Zip64Mode"));
Local JavaObject &setZip64Mode = &_class.getDeclaredMethod("setZip64Mode", &stringType);
Local JavaObject &args = CreateJavaObject("java.lang.Object[]", &javaString);
&setZip64Mode.invoke(&_workbook, &args);
&_class = Null;
这会执行,但根本不会改变输出文件的大小。
GetJavaClass(org.apache.commons.compress.archivers.zip.Zip64Mode).valueOf("从不");返回字符串值“org.apache.commons.compress.archivers.zip.Zip64Mode”而不是“Never”。
setZip64Mode(org.apache.commons.compress.archivers.zip.Zip64Mode zip64Mode)
我错过了什么?
经过大量研究和附加信息,下面的代码可以按预期工作。
&_class = &_workbook.getClass();
Local JavaObject &javaString = GetJavaClass("org.apache.commons.compress.archivers.zip.Zip64Mode").valueOf("Never");
Local JavaObject &stringType = CreateJavaObject("java.lang.Class[]", GetJavaClass("org.apache.commons.compress.archivers.zip.Zip64Mode"));
Local JavaObject &setZip64Mode = &_class.getDeclaredMethod("setZip64Mode", &stringType);
Local JavaObject &args = CreateJavaObject("java.lang.Object[]", &javaString);
&setZip64Mode.invoke(&_workbook, &args);
&_class = Null;
但是,我们发现如果 java 方法不存在或者未使用正确的语法(参数类型)调用它,Peoplecode 会给出相同的错误
可以使用下面的代码代替上面显示的反射代码:
Local JavaObject &enumValue = CreateJavaObject("java.lang.String", "Never");
&_workbook.setZip64Mode(GetJavaClass("org.apache.commons.compress.archivers.zip.Zip64Mode").valueOf(&enumValue));
虽然文件大小没有改变,但在打开阅读时观察到不会产生 zip-bomb 错误。这才是真正的问题。为了检查文件是否可以成功处理,使用 Araxis-Merge 来验证文件。