출처:
마이그레이션 방법: https://jxls.sourceforge.net/migration-to-v3-0.html
Jxls 사용법: https://jxls.sourceforge.net/getting-started.html
https://jxls.sourceforge.net/builder.html
주요 변경사항
- JxlsHelper -> new builder API
- All options can now be set in the builder with a Fluent API
- The TransformerFactory and createTransformer() methods have also been removed.
등등등 문서 보면 나옴.
결론
① userlib에 기존 파일 삭제 jxls
② 코드 수정
jxlser>implements>JxlserProcessor.java 만 수정하면 된다.
package jxlser.implementation;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.jxls.command.ImageCommand;
import org.jxls.transform.poi.JxlsPoiTemplateFillerBuilder;
import com.mendix.core.Core;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.systemwideinterfaces.core.meta.IMetaObject;
import system.proxies.FileDocument;
public class JxlserProcessor {
public static void doProcessTemplate(IContext mxcontext, InputStream templateIs, FileDocument mergedXlsFile, String targetCell) throws Exception {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
Map<String, Object> jxcontext = new HashMap<String, Object>();
Map<String, Object> params = JxlserParameterUtil.getNextParameters();
for (String key : params.keySet()) {
Object param = params.get(key);
if (param instanceof List) {
List<IMendixObject> moList = (List<IMendixObject>)param;
List<Object> proxyList = new ArrayList<Object>();
for (IMendixObject mo: moList) {
proxyList.add(toProxyObject(mxcontext, mo));
}
jxcontext.put(key, proxyList);
} else {
jxcontext.put(key, toProxyObject(mxcontext, (IMendixObject)params.get(key)));
}
}
File temp = File.createTempFile("template_", ".xls"); // 임시 파일 생성
temp.deleteOnExit(); // 프로그램 종료 시 임시 파일 삭제
if (targetCell != null && !targetCell.equals("")) {
JxlsPoiTemplateFillerBuilder.newInstance().withTemplate(templateIs).buildAndFill(jxcontext, temp);
} else {
JxlsPoiTemplateFillerBuilder.newInstance().withTemplate(templateIs).buildAndFill(jxcontext, temp);
}
Core.storeFileDocumentContent(mxcontext, mergedXlsFile.getMendixObject(),
new ByteArrayInputStream(FileUtils.readFileToByteArray(temp)));
} catch (IOException e) {
e.printStackTrace();
}
}
private static Object toProxyObject(IContext mxcontext, IMendixObject mo) throws Exception
{
if (mo == null) {
return null;
}
IMetaObject meta = mo.getMetaObject();
if (meta.getSuperObject() != null && meta.getSuperObject().getName().equals("System.Image")) {
InputStream is = Core.getImage(mxcontext, mo, false);
return ImageCommand.toByteArray(is);
} else {
String proxyClassName = meta.getModuleName().toLowerCase() + ".proxies." + meta.getName().replace(meta.getModuleName()+".", "");
Class clazz = Class.forName(proxyClassName);
Method initializeer = clazz.getDeclaredMethod("initialize", IContext.class, IMendixObject.class);
Object proxy = initializeer.invoke(null, mxcontext, mo);
return proxy;
}
}
}
③ Excel 파일 작성
direction="RIGHT"을 쓰기위해서는 lastCell을 정확하게 줘야한다. lastCell="C3"으로 주면 공백도 같이 반복된다.
name1 빈칸 name2 빈칸 name3 빈칸 이런식으로 반영된다.
④ MF 작성
결과 화면
==
과정
userlib에 파일을 변경한 후 실행을 시키면 에러가 발생한다.
C:\Users\YourPCName\Mendix\SampleApp-branch-poi-upgrade\javasource\jxlser\implementation\JxlserProcessor.java:12: error: cannot find symbol
import org.jxls.util.JxlsHelper;
^
symbol: class JxlsHelper
location: package org.jxls.util
C:\Users\YourPCName\Mendix\SampleApp-branch-poi-upgrade\javasource\jxlser\implementation\JxlserProcessor.java:13: error: cannot find symbol
import org.jxls.util.Util;
^
symbol: class Util
location: package org.jxls.util
C:\Users\YourPCName\Mendix\SampleApp-branch-poi-upgrade\javasource\jxlser\implementation\JxlserProcessor.java:27: error: Context is abstract; cannot be instantiated
org.jxls.common.Context jxcontext = new org.jxls.common.Context();
^
C:\Users\YourPCName\Mendix\SampleApp-branch-poi-upgrade\javasource\jxlser\implementation\JxlserProcessor.java:43: error: cannot find symbol
JxlsHelper.getInstance().processTemplateAtCell(templateIs, os, jxcontext, targetCell);
^
symbol: variable JxlsHelper
location: class JxlserProcessor
C:\Users\YourPCName\Mendix\SampleApp-branch-poi-upgrade\javasource\jxlser\implementation\JxlserProcessor.java:45: error: cannot find symbol
JxlsHelper.getInstance().processTemplate(templateIs, os, jxcontext);
^
symbol: variable JxlsHelper
location: class JxlserProcessor
C:\Users\YourPCName\Mendix\SampleApp-branch-poi-upgrade\javasource\jxlser\implementation\JxlserProcessor.java:64: error: cannot find symbol
return Util.toByteArray(is);
^
symbol: variable Util
location: class JxlserProcessor
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
6 errors
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compile'.
> Compilation failed; see the compiler error output for details.
* Try:
> Run with --scan to get full insights.
BUILD FAILED in 1s
마켓플레이스에서 다운로드 받은 Jxls에서 문제가 발생한다. Exclipse를 실행하여 해당 파일을 찾는다.
jxlser.implementaion > JxlserProcessor.java
package jxlser.implementation;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.jxls.util.JxlsHelper;
import org.jxls.util.Util;
import com.mendix.core.Core;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.systemwideinterfaces.core.meta.IMetaObject;
import system.proxies.FileDocument;
먼저 import 를 보면 문제가 되는 영역은 아래와 같다.
import org.jxls.util.JxlsHelper;
import org.jxls.util.Util;
3.0.0으로 변경하면서 util이 변경되어 찾을 수 없어 에러가 발생한다. 둘 다 사용 불가함으로 삭제한다.
Context 대신 Map<String, Object> (이를 "data"라고 함)을 사용한다.
특별한 Map 동작이 필요한 경우 MapDelegator<String, Object>를 기본 클래스로 사용할 수 있다. 하나 또는 몇 개의 메서드를 덮어쓰기만 하면 된다.
Context.putVar() 대신 Map.put()을 호출한다. 이와 같은 호출이 많으면 putVar() 메서드로 자체 HashMap 구현을 만들 수 있습니다.
Util.toByteArray() has been moved to ImageCommand. There's also a useful copy(InputStream, OutputStream) method in ImageCommand.
jx:params(formulaStrategy="BY_COLUMN")
'Mendix > Document' 카테고리의 다른 글
Mendix 프로젝트를 git에 올리는 방법 (0) | 2024.12.05 |
---|---|
[Mendix] Local에서 작업한 프로젝트 server에 올리기 (0) | 2024.11.27 |
[Mendix] Pluggable Widget (0) | 2024.11.13 |
[Mendix] PDF Document Generation (0) | 2024.05.27 |
[Mendix] 배포 방법 (0) | 2024.01.29 |