This commit is contained in:
kk
2026-07-07 18:01:21 +08:00
commit b259f94d4b
1088 changed files with 121778 additions and 0 deletions
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.build;
/**
* @author Jacky.gao
* @since 2017年6月19日
*/
public class Splash {
public void doPrint() {
String sb = "\n" +
" ___ ___ ________ _______ ________ ________ ________ _________ ________ \n" +
"|\\ \\|\\ \\|\\ __ \\|\\ ___ \\ |\\ __ \\|\\ __ \\|\\ __ \\|\\___ ___\\ |\\_____ \\ \n" +
"\\ \\ \\\\\\ \\ \\ \\|\\ \\ \\ __/|\\ \\ \\|\\ \\ \\ \\|\\ \\ \\ \\|\\ \\|___ \\ \\_| \\|____|\\ /_ \n" +
" \\ \\ \\\\\\ \\ \\ _ _\\ \\ \\_|/_\\ \\ ____\\ \\ \\\\\\ \\ \\ _ _\\ \\ \\ \\ \\|\\ \\ \n" +
" \\ \\ \\\\\\ \\ \\ \\\\ \\\\ \\ \\_|\\ \\ \\ \\___|\\ \\ \\\\\\ \\ \\ \\\\ \\| \\ \\ \\ __\\_\\ \\ \n" +
" \\ \\_______\\ \\__\\\\ _\\\\ \\_______\\ \\__\\ \\ \\_______\\ \\__\\\\ _\\ \\ \\__\\ |\\_______\\\n" +
" \\|_______|\\|__|\\|__|\\|_______|\\|__| \\|_______|\\|__|\\|__| \\|__| \\|_______|\n" +
"........................................................................................................" +
"\n" +
". uReport, is a Chinese style report engine" +
" licensed under the Apache License 2.0, ." +
"\n" +
". which is opensource, easy to use,high-performance, with browser-based-designer, ." +
"\n" +
". it has now been upgraded by BladeX to support jdk 17 and spring boot 3. ." +
"\n" +
"........................................................................................................" +
"\n";
System.out.println(sb);
}
}
@@ -0,0 +1,150 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.build.compute;
import com.bstek.ureport.build.BindData;
import com.bstek.ureport.build.Context;
import com.bstek.ureport.definition.value.Source;
import com.bstek.ureport.definition.value.ValueType;
import com.bstek.ureport.definition.value.ZxingValue;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.expression.model.Expression;
import com.bstek.ureport.expression.model.data.BindDataListExpressionData;
import com.bstek.ureport.expression.model.data.ExpressionData;
import com.bstek.ureport.expression.model.data.ObjectExpressionData;
import com.bstek.ureport.expression.model.data.ObjectListExpressionData;
import com.bstek.ureport.model.Cell;
import com.bstek.ureport.model.Image;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.tool.utils.Base64Util;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年3月27日
*/
public class ZxingValueCompute implements ValueCompute {
private static final int BLACK = 0xff000000;
private static final int WHITE = 0xFFFFFFFF;
@Override
public List<BindData> compute(Cell cell, Context context) {
List<BindData> list=new ArrayList<BindData>();
ZxingValue value=(ZxingValue)cell.getValue();
String format=value.getFormat();
BarcodeFormat barcodeForamt=BarcodeFormat.QR_CODE;
if(StringUtils.isNotBlank(format)){
barcodeForamt=BarcodeFormat.valueOf(format);
}
int w=value.getWidth();
int h=value.getHeight();
Source source=value.getSource();
if(source.equals(Source.text)){
String data=value.getValue();
Image image=buildImage(barcodeForamt,data,w,h);
list.add(new BindData(image));
}else{
Expression expression=value.getExpression();
ExpressionData<?> data=expression.execute(cell,cell, context);
if(data instanceof BindDataListExpressionData){
BindDataListExpressionData listData=(BindDataListExpressionData)data;
List<BindData> bindDataList=listData.getData();
for(BindData bindData:bindDataList){
Object obj=bindData.getValue();
if(obj==null)obj="";
Image image=buildImage(barcodeForamt,obj.toString(),w,h);
list.add(new BindData(image));
}
}else if(data instanceof ObjectExpressionData){
ObjectExpressionData exprData=(ObjectExpressionData)data;
Object obj=exprData.getData();
if(obj==null){
obj="";
}else if(obj instanceof String){
String text=obj.toString();
if(text.startsWith("\"") && text.endsWith("\"")){
text=text.substring(1,text.length()-1);
}
obj=text;
}
Image image=buildImage(barcodeForamt,obj.toString(),w,h);
list.add(new BindData(image));
}else if(data instanceof ObjectListExpressionData){
ObjectListExpressionData listExprData=(ObjectListExpressionData)data;
List<?> listData=listExprData.getData();
for(Object obj:listData){
if(obj==null){
obj="";
}else if(obj instanceof String){
String text=obj.toString();
if(text.startsWith("\"") && text.endsWith("\"")){
text=text.substring(1,text.length()-1);
}
obj=text;
}
Image image=buildImage(barcodeForamt,obj.toString(),w,h);
list.add(new BindData(image));
}
}
}
return list;
}
private Image buildImage(BarcodeFormat format,String data,int w,int h){
try{
Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN,0);
if(format.equals(BarcodeFormat.QR_CODE)){
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
}
BitMatrix matrix = new MultiFormatWriter().encode(data,format, w, h,hints);
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
byte[] bytes=outputStream.toByteArray();
String base64Data= Base64Util.encodeToString(bytes);
IOUtils.closeQuietly(outputStream);
return new Image(base64Data,w,h);
}catch(Exception ex){
throw new ReportComputeException(ex);
}
}
@Override
public ValueType type() {
return ValueType.zxing;
}
}
@@ -0,0 +1,125 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2016年6月3日
*/
public abstract class BaseServletAction implements ServletAction {
protected Throwable buildRootException(Throwable throwable) {
if (throwable.getCause() == null) {
return throwable;
}
return buildRootException(throwable.getCause());
}
protected String decode(String value) {
if (value == null) {
return value;
}
try {
value = URLDecoder.decode(value, "utf-8");
value = URLDecoder.decode(value, "utf-8");
return value;
} catch (Exception ex) {
return value;
}
}
protected String decodeContent(String content) {
if (content == null) {
return content;
}
try {
content = URLDecoder.decode(content, "utf-8");
return content;
} catch (Exception ex) {
return content;
}
}
protected Map<String, Object> buildParameters(HttpServletRequest req) {
Map<String, Object> parameters = new HashMap<String, Object>();
Enumeration<?> enumeration = req.getParameterNames();
while (enumeration.hasMoreElements()) {
Object obj = enumeration.nextElement();
if (obj == null) {
continue;
}
String name = obj.toString();
String value = req.getParameter(name);
if (name == null || value == null || name.startsWith("_")) {
continue;
}
parameters.put(name, decode(value));
}
return parameters;
}
protected void invokeMethod(String methodName, HttpServletRequest req, HttpServletResponse resp) throws ServletException {
try {
Method method = this.getClass().getMethod(methodName, new Class<?>[]{HttpServletRequest.class, HttpServletResponse.class});
method.invoke(this, new Object[]{req, resp});
} catch (Exception ex) {
throw new ServletException(ex);
}
}
protected String retriveMethod(HttpServletRequest req) throws ServletException {
String path = req.getContextPath() + UReportServlet.URL;
String uri = req.getRequestURI();
String targetUrl = uri.substring(path.length());
int slashPos = targetUrl.indexOf("/", 1);
if (slashPos > -1) {
String methodName = targetUrl.substring(slashPos + 1).trim();
return methodName.length() > 0 ? methodName : null;
}
return null;
}
protected String buildDownloadFileName(String reportFileName, String fileName, String extName) {
if (StringUtils.isNotBlank(fileName)) {
fileName = decode(fileName);
if (!fileName.toLowerCase().endsWith(extName)) {
fileName = fileName + extName;
}
return fileName;
} else {
int pos = reportFileName.indexOf(":");
if (pos > 0) {
reportFileName = reportFileName.substring(pos + 1, reportFileName.length());
}
pos = reportFileName.toLowerCase().indexOf(".ureport.xml");
if (pos > 0) {
reportFileName = reportFileName.substring(0, pos);
}
return "ureport-" + reportFileName + extName;
}
}
}
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console;
import jakarta.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Jacky.gao
* @since 2017年10月11日
*/
public class MobileUtils {
private static String phoneReg = "\\b(ip(hone|od)|android|opera m(ob|in)i"
+ "|windows (phone|ce)|blackberry"
+ "|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp"
+ "|laystation portable)|nokia|fennec|htc[-_]"
+ "|mobile|up.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";
private static String tableReg = "\\b(ipad|tablet|(Nexus 7)|up.browser"
+ "|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";
private static Pattern phonePat = Pattern.compile(phoneReg, Pattern.CASE_INSENSITIVE);
private static Pattern tablePat = Pattern.compile(tableReg, Pattern.CASE_INSENSITIVE);
public static boolean isMobile(HttpServletRequest req) {
String userAgent = req.getHeader("USER-AGENT");
if (userAgent == null) {
userAgent = "";
}
userAgent = userAgent.toLowerCase();
Matcher matcherPhone = phonePat.matcher(userAgent);
Matcher matcherTable = tablePat.matcher(userAgent);
if (matcherPhone.find() || matcherTable.find()) {
return true;
} else {
return false;
}
}
}
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console;
import jakarta.servlet.http.HttpServletRequest;
/**
* @author Jacky.gao
* @since 2017年3月8日
*/
public class RequestHolder {
private static final ThreadLocal<HttpServletRequest> requestThreadLocal = new ThreadLocal<HttpServletRequest>();
public static void setRequest(HttpServletRequest request) {
requestThreadLocal.set(request);
}
public static HttpServletRequest getRequest() {
return requestThreadLocal.get();
}
public static void clean() {
requestThreadLocal.remove();
}
}
@@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Jacky.gao
* @since 2017年1月25日
*/
public interface ServletAction {
public static final String PREVIEW_KEY = "p";
void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
String url();
}
@@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年1月25日
*/
public class UReportServlet extends HttpServlet {
private static final long serialVersionUID = 533049461276487971L;
public static final String URL = "/ureport";
private Map<String, ServletAction> actionMap = new HashMap<String, ServletAction>();
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
WebApplicationContext applicationContext = getWebApplicationContext(config);
Collection<ServletAction> handlers = applicationContext.getBeansOfType(ServletAction.class).values();
for (ServletAction handler : handlers) {
String url = handler.url();
if (actionMap.containsKey(url)) {
throw new RuntimeException("Handler [" + url + "] already exist.");
}
actionMap.put(url, handler);
}
}
protected WebApplicationContext getWebApplicationContext(ServletConfig config) {
return WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getContextPath() + URL;
String uri = req.getRequestURI();
String targetUrl = uri.substring(path.length());
if (targetUrl.length() < 1) {
outContent(resp, "Welcome to use ureport,please specify target url.");
return;
}
int slashPos = targetUrl.indexOf("/", 1);
if (slashPos > -1) {
targetUrl = targetUrl.substring(0, slashPos);
}
ServletAction targetHandler = actionMap.get(targetUrl);
if (targetHandler == null) {
outContent(resp, "Handler [" + targetUrl + "] not exist.");
return;
}
RequestHolder.setRequest(req);
try {
targetHandler.execute(req, resp);
} catch (Exception ex) {
resp.setCharacterEncoding("UTF-8");
PrintWriter pw = resp.getWriter();
Throwable e = buildRootException(ex);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
String errorMsg = e.getMessage();
if (StringUtils.isBlank(errorMsg)) {
errorMsg = e.getClass().getName();
}
pw.write(errorMsg);
pw.close();
throw new ServletException(ex);
} finally {
RequestHolder.clean();
}
}
private Throwable buildRootException(Throwable throwable) {
if (throwable.getCause() == null) {
return throwable;
}
return buildRootException(throwable.getCause());
}
private void outContent(HttpServletResponse resp, String msg) throws IOException {
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.write("<html>");
pw.write("<header><title>UReport Console</title></header>");
pw.write("<body>");
pw.write(msg);
pw.write("</body>");
pw.write("</html>");
pw.flush();
pw.close();
}
}
@@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
/**
* @author Jacky.gao
* @since 2016年5月23日
*/
public abstract class WriteJsonServletAction extends BaseServletAction {
protected void writeObjectToJson(HttpServletResponse resp, Object obj) throws ServletException, IOException {
resp.setContentType("text/json");
resp.setCharacterEncoding("UTF-8");
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Inclusion.NON_NULL);
mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
OutputStream out = resp.getOutputStream();
try {
mapper.writeValue(out, obj);
} finally {
out.flush();
out.close();
}
}
}
@@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.cache;
import com.bstek.ureport.cache.ReportCache;
import com.bstek.ureport.console.RequestHolder;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年3月8日
*/
public class HttpSessionReportCache implements ReportCache {
private Map<String, ObjectMap> sessionReportMap = new HashMap<String, ObjectMap>();
private boolean disabled;
@Override
public Object getObject(String file) {
HttpServletRequest req = RequestHolder.getRequest();
if (req == null) {
return null;
}
ObjectMap objMap = getObjectMap(req);
return objMap.get(file);
}
@Override
public void storeObject(String file, Object object) {
HttpServletRequest req = RequestHolder.getRequest();
if (req == null) {
return;
}
ObjectMap map = getObjectMap(req);
map.put(file, object);
}
@Override
public boolean disabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
private ObjectMap getObjectMap(HttpServletRequest req) {
List<String> expiredList = new ArrayList<String>();
for (String key : sessionReportMap.keySet()) {
ObjectMap reportObj = sessionReportMap.get(key);
if (reportObj.isExpired()) {
expiredList.add(key);
}
}
for (String key : expiredList) {
sessionReportMap.remove(key);
}
String sessionId = req.getSession().getId();
ObjectMap obj = sessionReportMap.get(sessionId);
if (obj != null) {
return obj;
} else {
ObjectMap objMap = new ObjectMap();
sessionReportMap.put(sessionId, objMap);
return objMap;
}
}
}
@@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.cache;
import com.bstek.ureport.console.RequestHolder;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年9月6日
*/
public class TempObjectCache {
private static TempObjectCache tempObjectCache = new TempObjectCache();
private Map<String, ObjectMap> sessionMap = new HashMap<String, ObjectMap>();
public static Object getObject(String key) {
return tempObjectCache.get(key);
}
public static void putObject(String key, Object obj) {
tempObjectCache.store(key, obj);
}
public static void removeObject(String key) {
tempObjectCache.remove(key);
}
public void remove(String key) {
HttpServletRequest req = RequestHolder.getRequest();
if (req == null) {
return;
}
ObjectMap mapObject = getReportMap(req);
if (mapObject != null) {
mapObject.remove(key);
}
}
public Object get(String key) {
HttpServletRequest req = RequestHolder.getRequest();
if (req == null) {
return null;
}
ObjectMap mapObject = getReportMap(req);
return mapObject.get(key);
}
public void store(String key, Object obj) {
HttpServletRequest req = RequestHolder.getRequest();
if (req == null) {
return;
}
ObjectMap mapObject = getReportMap(req);
mapObject.put(key, obj);
}
private ObjectMap getReportMap(HttpServletRequest req) {
List<String> expiredList = new ArrayList<String>();
for (String key : sessionMap.keySet()) {
ObjectMap reportObj = sessionMap.get(key);
if (reportObj.isExpired()) {
expiredList.add(key);
}
}
for (String key : expiredList) {
sessionMap.remove(key);
}
String sessionId = req.getSession().getId();
ObjectMap obj = sessionMap.get(sessionId);
if (obj != null) {
return obj;
} else {
ObjectMap mapObject = new ObjectMap();
sessionMap.put(sessionId, mapObject);
return mapObject;
}
}
}
@@ -0,0 +1,67 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.chart;
import com.bstek.ureport.cache.CacheUtils;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.console.RenderPageServletAction;
import com.bstek.ureport.utils.UnitUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Jacky.gao
* @since 2017年6月30日
*/
public class ChartServletAction extends RenderPageServletAction {
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
}
}
public void storeData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("_u");
file = decode(file);
String chartId = req.getParameter("_chartId");
ChartData chartData = CacheUtils.getChartData(chartId);
if (chartData == null) {
return;
}
String base64Data = req.getParameter("_base64Data");
String prefix = "data:image/png;base64,";
if (base64Data != null) {
if (base64Data.startsWith(prefix)) {
base64Data = base64Data.substring(prefix.length(), base64Data.length());
}
}
chartData.setBase64Data(base64Data);
String width = req.getParameter("_width");
String height = req.getParameter("_height");
chartData.setHeight(UnitUtils.pixelToPoint(Integer.valueOf(height)));
chartData.setWidth(UnitUtils.pixelToPoint(Integer.valueOf(width)));
}
@Override
public String url() {
return "/chart";
}
}
@@ -0,0 +1,385 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.designer;
import com.bstek.ureport.Utils;
import com.bstek.ureport.build.Context;
import com.bstek.ureport.console.RenderPageServletAction;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.dataset.Field;
import com.bstek.ureport.definition.datasource.BuildinDatasource;
import com.bstek.ureport.definition.datasource.DataType;
import com.bstek.ureport.expression.ExpressionUtils;
import com.bstek.ureport.expression.model.Expression;
import com.bstek.ureport.expression.model.data.ExpressionData;
import com.bstek.ureport.expression.model.data.ObjectExpressionData;
import com.bstek.ureport.utils.ProcedureUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.*;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.jdbc.support.JdbcUtils;
import javax.sql.DataSource;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.Date;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Jacky.gao
* @since 2017年2月6日
*/
public class DatasourceServletAction extends RenderPageServletAction {
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
}
}
public void loadBuildinDatasources(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<String> datasources = new ArrayList<String>();
for (BuildinDatasource datasource : Utils.getBuildinDatasources()) {
datasources.add(datasource.name());
}
writeObjectToJson(resp, datasources);
}
public void loadMethods(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String beanId = req.getParameter("beanId");
Object obj = applicationContext.getBean(beanId);
Class<?> clazz = obj.getClass();
Method[] methods = clazz.getMethods();
List<String> result = new ArrayList<String>();
for (Method method : methods) {
Class<?>[] types = method.getParameterTypes();
if (types.length != 3) {
continue;
}
Class<?> typeClass1 = types[0];
Class<?> typeClass2 = types[1];
Class<?> typeClass3 = types[2];
if (!String.class.isAssignableFrom(typeClass1)) {
continue;
}
if (!String.class.isAssignableFrom(typeClass2)) {
continue;
}
if (!Map.class.isAssignableFrom(typeClass3)) {
continue;
}
result.add(method.getName());
}
writeObjectToJson(resp, result);
}
public void buildClass(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String clazz = req.getParameter("clazz");
List<Field> result = new ArrayList<Field>();
try {
Class<?> targetClass = Class.forName(clazz);
PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(targetClass);
for (PropertyDescriptor pd : propertyDescriptors) {
String name = pd.getName();
if ("class".equals(name)) {
continue;
}
result.add(new Field(name));
}
writeObjectToJson(resp, result);
} catch (Exception ex) {
throw new ReportDesignException(ex);
}
}
public void buildDatabaseTables(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Connection conn = null;
ResultSet rs = null;
try {
conn = buildConnection(req);
DatabaseMetaData metaData = conn.getMetaData();
String url = metaData.getURL();
String schema = null;
if (url.toLowerCase().contains("oracle")) {
schema = metaData.getUserName();
}
List<Map<String, String>> tables = new ArrayList<Map<String, String>>();
rs = metaData.getTables(null, schema, "%", new String[]{"TABLE", "VIEW"});
while (rs.next()) {
Map<String, String> table = new HashMap<String, String>();
table.put("name", rs.getString("TABLE_NAME"));
table.put("type", rs.getString("TABLE_TYPE"));
tables.add(table);
}
writeObjectToJson(resp, tables);
} catch (Exception ex) {
throw new ServletException(ex);
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeConnection(conn);
}
}
public void buildFields(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sql = req.getParameter("sql");
String parameters = req.getParameter("parameters");
Connection conn = null;
final List<Field> fields = new ArrayList<Field>();
try {
conn = buildConnection(req);
Map<String, Object> map = buildParameters(parameters);
sql = parseSql(sql, map);
if (ProcedureUtils.isProcedure(sql)) {
List<Field> fieldsList = ProcedureUtils.procedureColumnsQuery(sql, map, conn);
fields.addAll(fieldsList);
} else {
DataSource dataSource = new SingleConnectionDataSource(conn, false);
NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(dataSource);
PreparedStatementCreator statementCreator = getPreparedStatementCreator(sql, new MapSqlParameterSource(map));
jdbc.getJdbcOperations().execute(statementCreator, new PreparedStatementCallback<Object>() {
@Override
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
ResultSet rs = null;
try {
rs = ps.executeQuery();
ResultSetMetaData metadata = rs.getMetaData();
int columnCount = metadata.getColumnCount();
for (int i = 0; i < columnCount; i++) {
String columnName = metadata.getColumnLabel(i + 1);
fields.add(new Field(columnName));
}
return null;
} finally {
JdbcUtils.closeResultSet(rs);
}
}
});
}
writeObjectToJson(resp, fields);
} catch (Exception ex) {
throw new ReportDesignException(ex);
} finally {
JdbcUtils.closeConnection(conn);
}
}
protected PreparedStatementCreator getPreparedStatementCreator(String sql, SqlParameterSource paramSource) {
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null);
List<SqlParameter> declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource);
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters);
return pscf.newPreparedStatementCreator(params);
}
public void previewData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sql = req.getParameter("sql");
String parameters = req.getParameter("parameters");
Map<String, Object> map = buildParameters(parameters);
sql = parseSql(sql, map);
Connection conn = null;
try {
conn = buildConnection(req);
List<Map<String, Object>> list = null;
if (ProcedureUtils.isProcedure(sql)) {
list = ProcedureUtils.procedureQuery(sql, map, conn);
} else {
DataSource dataSource = new SingleConnectionDataSource(conn, false);
NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(dataSource);
list = jdbc.queryForList(sql, map);
}
int size = list.size();
int currentTotal = size;
if (currentTotal > 500) {
currentTotal = 500;
}
List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
for (int i = 0; i < currentTotal; i++) {
ls.add(list.get(i));
}
DataResult result = new DataResult();
List<String> fields = new ArrayList<String>();
if (size > 0) {
Map<String, Object> item = list.get(0);
for (String name : item.keySet()) {
fields.add(name);
}
}
result.setFields(fields);
result.setCurrentTotal(currentTotal);
result.setData(ls);
result.setTotal(size);
writeObjectToJson(resp, result);
} catch (Exception ex) {
throw new ServletException(ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
private String parseSql(String sql, Map<String, Object> parameters) {
sql = sql.trim();
Context context = new Context(applicationContext, parameters);
if (sql.startsWith(ExpressionUtils.EXPR_PREFIX) && sql.endsWith(ExpressionUtils.EXPR_SUFFIX)) {
sql = sql.substring(2, sql.length() - 1);
Expression expr = ExpressionUtils.parseExpression(sql);
sql = executeSqlExpr(expr, context);
return sql;
} else {
String sqlForUse = sql;
Pattern pattern = Pattern.compile("\\$\\{.*?\\}");
Matcher matcher = pattern.matcher(sqlForUse);
while (matcher.find()) {
String substr = matcher.group();
String sqlExpr = substr.substring(2, substr.length() - 1);
Expression expr = ExpressionUtils.parseExpression(sqlExpr);
String result = executeSqlExpr(expr, context);
sqlForUse = sqlForUse.replace(substr, result);
}
Utils.logToConsole("DESIGN SQL:" + sqlForUse);
return sqlForUse;
}
}
private String executeSqlExpr(Expression sqlExpr, Context context) {
String sqlForUse = null;
ExpressionData<?> exprData = sqlExpr.execute(null, null, context);
if (exprData instanceof ObjectExpressionData) {
ObjectExpressionData data = (ObjectExpressionData) exprData;
Object obj = data.getData();
if (obj != null) {
String s = obj.toString();
s = s.replaceAll("\\\\", "");
sqlForUse = s;
}
}
return sqlForUse;
}
public void testConnection(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String driver = req.getParameter("driver");
String url = req.getParameter("url");
Connection conn = null;
Map<String, Object> map = new HashMap<String, Object>();
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
map.put("result", true);
} catch (Exception ex) {
map.put("error", ex.toString());
map.put("result", false);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
writeObjectToJson(resp, map);
}
@SuppressWarnings("unchecked")
private Map<String, Object> buildParameters(String parameters) throws IOException, JsonParseException, JsonMappingException {
Map<String, Object> map = new HashMap<String, Object>();
if (StringUtils.isBlank(parameters)) {
return map;
}
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> list = mapper.readValue(parameters, ArrayList.class);
for (Map<String, Object> param : list) {
String name = param.get("name").toString();
DataType type = DataType.valueOf(param.get("type").toString());
String defaultValue = (String) param.get("defaultValue");
if (defaultValue == null || defaultValue.isEmpty()) {
switch (type) {
case Boolean:
map.put(name, false);
case Date:
map.put(name, new Date());
case Float:
map.put(name, (float) 0);
case Integer:
map.put(name, 0);
case String:
if (defaultValue != null) {
map.put(name, "");
} else {
map.put(name, "null");
}
break;
case List:
map.put(name, new ArrayList<>());
}
} else {
map.put(name, type.parse(defaultValue));
}
}
return map;
}
private Connection buildConnection(HttpServletRequest req) throws Exception {
String type = req.getParameter("type");
if (type.equals("jdbc")) {
String username = req.getParameter("username");
String password = req.getParameter("password");
String driver = req.getParameter("driver");
String url = req.getParameter("url");
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
} else {
String name = req.getParameter("name");
Connection conn = Utils.getBuildinConnection(name);
if (conn == null) {
throw new ReportDesignException("Buildin datasource [" + name + "] not exist.");
}
return conn;
}
}
@Override
public String url() {
return "/datasource";
}
}
@@ -0,0 +1,213 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.designer;
import com.bstek.ureport.cache.CacheUtils;
import com.bstek.ureport.console.RenderPageServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.dsl.ReportParserLexer;
import com.bstek.ureport.dsl.ReportParserParser;
import com.bstek.ureport.dsl.ReportParserParser.DatasetContext;
import com.bstek.ureport.export.ReportRender;
import com.bstek.ureport.expression.ErrorInfo;
import com.bstek.ureport.expression.ScriptErrorListener;
import com.bstek.ureport.parser.ReportParser;
import com.bstek.ureport.provider.report.ReportProvider;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;
/**
* @author Jacky.gao
* @since 2017年1月25日
*/
public class DesignerServletAction extends RenderPageServletAction {
private ReportRender reportRender;
private ReportParser reportParser;
private List<ReportProvider> reportProviders = new ArrayList<ReportProvider>();
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
} else {
VelocityContext context = new VelocityContext();
context.put("contextPath", req.getContextPath());
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
Template template = ve.getTemplate("ureport-html/designer.html", "utf-8");
PrintWriter writer = resp.getWriter();
template.merge(context, writer);
writer.close();
}
}
public void scriptValidation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String content = req.getParameter("content");
ANTLRInputStream antlrInputStream = new ANTLRInputStream(content);
ReportParserLexer lexer = new ReportParserLexer(antlrInputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
ReportParserParser parser = new ReportParserParser(tokenStream);
ScriptErrorListener errorListener = new ScriptErrorListener();
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
parser.expression();
List<ErrorInfo> infos = errorListener.getInfos();
writeObjectToJson(resp, infos);
}
public void conditionScriptValidation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String content = req.getParameter("content");
ANTLRInputStream antlrInputStream = new ANTLRInputStream(content);
ReportParserLexer lexer = new ReportParserLexer(antlrInputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
ReportParserParser parser = new ReportParserParser(tokenStream);
ScriptErrorListener errorListener = new ScriptErrorListener();
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
parser.expr();
List<ErrorInfo> infos = errorListener.getInfos();
writeObjectToJson(resp, infos);
}
public void parseDatasetName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String expr = req.getParameter("expr");
ANTLRInputStream antlrInputStream = new ANTLRInputStream(expr);
ReportParserLexer lexer = new ReportParserLexer(antlrInputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
ReportParserParser parser = new ReportParserParser(tokenStream);
parser.removeErrorListeners();
DatasetContext ctx = parser.dataset();
String datasetName = ctx.Identifier().getText();
Map<String, String> result = new HashMap<String, String>();
result.put("datasetName", datasetName);
writeObjectToJson(resp, result);
}
public void savePreviewData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String content = req.getParameter("content");
content = decodeContent(content);
InputStream inputStream = IOUtils.toInputStream(content, "utf-8");
ReportDefinition reportDef = reportParser.parse(inputStream, "p");
reportRender.rebuildReportDefinition(reportDef);
IOUtils.closeQuietly(inputStream);
TempObjectCache.putObject(PREVIEW_KEY, reportDef);
}
public void loadReport(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("file");
if (file == null) {
throw new ReportDesignException("Report file can not be null.");
}
file = ReportUtils.decodeFileName(file);
Object obj = TempObjectCache.getObject(file);
if (obj != null && obj instanceof ReportDefinition) {
ReportDefinition reportDef = (ReportDefinition) obj;
TempObjectCache.removeObject(file);
writeObjectToJson(resp, new ReportDefinitionWrapper(reportDef));
} else {
ReportDefinition reportDef = reportRender.parseReport(file);
writeObjectToJson(resp, new ReportDefinitionWrapper(reportDef));
}
}
public void deleteReportFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("file");
if (file == null) {
throw new ReportDesignException("Report file can not be null.");
}
ReportProvider targetReportProvider = null;
for (ReportProvider provider : reportProviders) {
if (file.startsWith(provider.getPrefix())) {
targetReportProvider = provider;
break;
}
}
if (targetReportProvider == null) {
throw new ReportDesignException("File [" + file + "] not found available report provider.");
}
targetReportProvider.deleteReport(file);
}
public void saveReportFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("file");
file = ReportUtils.decodeFileName(file);
String content = req.getParameter("content");
content = decodeContent(content);
ReportProvider targetReportProvider = null;
for (ReportProvider provider : reportProviders) {
if (file.startsWith(provider.getPrefix())) {
targetReportProvider = provider;
break;
}
}
if (targetReportProvider == null) {
throw new ReportDesignException("File [" + file + "] not found available report provider.");
}
targetReportProvider.saveReport(file, content);
InputStream inputStream = IOUtils.toInputStream(content, "utf-8");
ReportDefinition reportDef = reportParser.parse(inputStream, file);
reportRender.rebuildReportDefinition(reportDef);
CacheUtils.cacheReportDefinition(file, reportDef);
IOUtils.closeQuietly(inputStream);
}
public void loadReportProviders(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
writeObjectToJson(resp, reportProviders);
}
public void setReportRender(ReportRender reportRender) {
this.reportRender = reportRender;
}
public void setReportParser(ReportParser reportParser) {
this.reportParser = reportParser;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
super.setApplicationContext(applicationContext);
Collection<ReportProvider> providers = applicationContext.getBeansOfType(ReportProvider.class).values();
for (ReportProvider provider : providers) {
if (provider.disabled() || provider.getName() == null) {
continue;
}
reportProviders.add(provider);
}
}
@Override
public String url() {
return "/designer";
}
}
@@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.designer;
import com.bstek.ureport.console.RenderPageServletAction;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author Jacky.gao
* @since 2017年10月24日
*/
public class SearchFormDesignerAction extends RenderPageServletAction {
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
VelocityContext context = new VelocityContext();
context.put("contextPath", req.getContextPath());
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
Template template = ve.getTemplate("ureport-html/searchform.html", "utf-8");
PrintWriter writer = resp.getWriter();
template.merge(context, writer);
writer.close();
}
@Override
public String url() {
return "/searchFormDesigner";
}
}
@@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.excel;
import com.bstek.ureport.build.ReportBuilder;
import com.bstek.ureport.console.BaseServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.ExportConfigure;
import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.excel.low.Excel97Producer;
import com.bstek.ureport.model.Report;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年7月3日
*/
public class ExportExcel97ServletAction extends BaseServletAction {
private ReportBuilder reportBuilder;
private ExportManager exportManager;
private Excel97Producer excelProducer = new Excel97Producer();
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
} else {
buildExcel(req, resp, false, false);
}
}
public void paging(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
buildExcel(req, resp, true, false);
}
public void sheet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
buildExcel(req, resp, false, true);
}
public void buildExcel(HttpServletRequest req, HttpServletResponse resp, boolean withPage, boolean withSheet) throws IOException {
String file = req.getParameter("_u");
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
String fileName = req.getParameter("_n");
if (StringUtils.isNotBlank(fileName)) {
fileName = decode(fileName);
} else {
fileName = "ureport.xls";
}
resp.setContentType("application/octet-stream;charset=ISO8859-1");
resp.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
Map<String, Object> parameters = buildParameters(req);
OutputStream outputStream = resp.getOutputStream();
if (file.equals(PREVIEW_KEY)) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export excel.");
}
Report report = reportBuilder.buildReport(reportDefinition, parameters);
if (withPage) {
excelProducer.produceWithPaging(report, outputStream);
} else if (withSheet) {
excelProducer.produceWithSheet(report, outputStream);
} else {
excelProducer.produce(report, outputStream);
}
} else {
ExportConfigure configure = new ExportConfigureImpl(file, parameters, outputStream);
if (withPage) {
exportManager.exportExcelWithPaging(configure);
} else if (withSheet) {
exportManager.exportExcelWithPagingSheet(configure);
} else {
exportManager.exportExcel(configure);
}
}
outputStream.flush();
outputStream.close();
}
public void setReportBuilder(ReportBuilder reportBuilder) {
this.reportBuilder = reportBuilder;
}
public void setExportManager(ExportManager exportManager) {
this.exportManager = exportManager;
}
@Override
public String url() {
return "/excel97";
}
}
@@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.excel;
import com.bstek.ureport.build.ReportBuilder;
import com.bstek.ureport.console.BaseServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.export.ExportConfigure;
import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.excel.high.ExcelProducer;
import com.bstek.ureport.model.Report;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年4月17日
*/
public class ExportExcelServletAction extends BaseServletAction {
private ReportBuilder reportBuilder;
private ExportManager exportManager;
private ExcelProducer excelProducer = new ExcelProducer();
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
} else {
buildExcel(req, resp, false, false);
}
}
public void paging(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
buildExcel(req, resp, true, false);
}
public void sheet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
buildExcel(req, resp, false, true);
}
public void buildExcel(HttpServletRequest req, HttpServletResponse resp, boolean withPage, boolean withSheet) throws IOException {
String file = req.getParameter("_u");
file = decode(file);
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
OutputStream outputStream = resp.getOutputStream();
try {
String fileName = req.getParameter("_n");
fileName = buildDownloadFileName(file, fileName, ".xlsx");
resp.setContentType("application/octet-stream;charset=ISO8859-1");
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
resp.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
Map<String, Object> parameters = buildParameters(req);
if (file.equals(PREVIEW_KEY)) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export excel.");
}
Report report = reportBuilder.buildReport(reportDefinition, parameters);
if (withPage) {
excelProducer.produceWithPaging(report, outputStream);
} else if (withSheet) {
excelProducer.produceWithSheet(report, outputStream);
} else {
excelProducer.produce(report, outputStream);
}
} else {
ExportConfigure configure = new ExportConfigureImpl(file, parameters, outputStream);
if (withPage) {
exportManager.exportExcelWithPaging(configure);
} else if (withSheet) {
exportManager.exportExcelWithPagingSheet(configure);
} else {
exportManager.exportExcel(configure);
}
}
} catch (Exception ex) {
throw new ReportException(ex);
} finally {
outputStream.flush();
outputStream.close();
}
}
public void setReportBuilder(ReportBuilder reportBuilder) {
this.reportBuilder = reportBuilder;
}
public void setExportManager(ExportManager exportManager) {
this.exportManager = exportManager;
}
@Override
public String url() {
return "/excel";
}
}
@@ -0,0 +1,365 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.html;
import com.bstek.ureport.build.Context;
import com.bstek.ureport.build.ReportBuilder;
import com.bstek.ureport.build.paging.Page;
import com.bstek.ureport.cache.CacheUtils;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.console.MobileUtils;
import com.bstek.ureport.console.RenderPageServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.Paper;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.definition.searchform.FormPosition;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.*;
import com.bstek.ureport.export.html.HtmlProducer;
import com.bstek.ureport.export.html.HtmlReport;
import com.bstek.ureport.export.html.SearchFormData;
import com.bstek.ureport.model.Report;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
/**
* @author Jacky.gao
* @since 2017年2月15日
*/
public class HtmlPreviewServletAction extends RenderPageServletAction {
private ExportManager exportManager;
private ReportBuilder reportBuilder;
private ReportRender reportRender;
private HtmlProducer htmlProducer = new HtmlProducer();
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
} else {
VelocityContext context = new VelocityContext();
HtmlReport htmlReport = null;
String errorMsg = null;
try {
htmlReport = loadReport(req);
} catch (Exception ex) {
if (!(ex instanceof ReportDesignException)) {
ex.printStackTrace();
}
errorMsg = buildExceptionMessage(ex);
}
String title = buildTitle(req);
context.put("title", title);
if (htmlReport == null) {
context.put("content", "<div style='color:red'><strong>报表计算出错,错误信息如下:</strong><br><div style=\"margin:10px\">" + errorMsg + "</div></div>");
context.put("error", true);
context.put("searchFormJs", "");
context.put("downSearchFormHtml", "");
context.put("upSearchFormHtml", "");
} else {
SearchFormData formData = htmlReport.getSearchFormData();
if (formData != null) {
context.put("searchFormJs", formData.getJs());
if (formData.getFormPosition().equals(FormPosition.up)) {
context.put("upSearchFormHtml", formData.getHtml());
context.put("downSearchFormHtml", "");
} else {
context.put("downSearchFormHtml", formData.getHtml());
context.put("upSearchFormHtml", "");
}
} else {
context.put("searchFormJs", "");
context.put("downSearchFormHtml", "");
context.put("upSearchFormHtml", "");
}
context.put("content", htmlReport.getContent());
context.put("style", htmlReport.getStyle());
context.put("reportAlign", htmlReport.getReportAlign());
context.put("totalPage", htmlReport.getTotalPage());
context.put("totalPageWithCol", htmlReport.getTotalPageWithCol());
context.put("pageIndex", htmlReport.getPageIndex());
context.put("chartDatas", convertJson(htmlReport.getChartDatas()));
context.put("error", false);
context.put("file", req.getParameter("_u"));
context.put("intervalRefreshValue", htmlReport.getHtmlIntervalRefreshValue());
String customParameters = buildCustomParameters(req);
context.put("customParameters", customParameters);
context.put("_t", "");
Tools tools = null;
if (MobileUtils.isMobile(req)) {
tools = new Tools(false);
tools.setShow(false);
} else {
String toolsInfo = req.getParameter("_t");
if (StringUtils.isNotBlank(toolsInfo)) {
tools = new Tools(false);
if (toolsInfo.equals("0")) {
tools.setShow(false);
} else {
String[] infos = toolsInfo.split(",");
for (String name : infos) {
tools.doInit(name);
}
}
context.put("_t", toolsInfo);
context.put("hasTools", true);
} else {
tools = new Tools(true);
}
}
context.put("tools", tools);
}
context.put("contextPath", req.getContextPath());
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
Template template = ve.getTemplate("ureport-html/html-preview.html", "utf-8");
PrintWriter writer = resp.getWriter();
template.merge(context, writer);
writer.close();
}
}
private String buildTitle(HttpServletRequest req) {
String title = req.getParameter("_title");
if (StringUtils.isBlank(title)) {
title = req.getParameter("_u");
title = decode(title);
int point = title.lastIndexOf(".ureport.xml");
if (point > -1) {
title = title.substring(0, point);
}
if (title.equals("p")) {
title = "设计中报表";
}
} else {
title = decode(title);
}
return title + "-ureport";
}
private String convertJson(Collection<ChartData> data) {
if (data == null || data.size() == 0) {
return "";
}
ObjectMapper mapper = new ObjectMapper();
try {
String json = mapper.writeValueAsString(data);
return json;
} catch (Exception e) {
throw new ReportComputeException(e);
}
}
public void loadData(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HtmlReport htmlReport = loadReport(req);
writeObjectToJson(resp, htmlReport);
}
public void loadPrintPages(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("_u");
file = decode(file);
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
Map<String, Object> parameters = buildParameters(req);
ReportDefinition reportDefinition = null;
if (file.equals(PREVIEW_KEY)) {
reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export excel.");
}
} else {
reportDefinition = reportRender.getReportDefinition(file);
}
Report report = reportBuilder.buildReport(reportDefinition, parameters);
Map<String, ChartData> chartMap = report.getContext().getChartDataMap();
if (chartMap.size() > 0) {
CacheUtils.storeChartDataMap(chartMap);
}
FullPageData pageData = PageBuilder.buildFullPageData(report);
StringBuilder sb = new StringBuilder();
List<List<Page>> list = pageData.getPageList();
Context context = report.getContext();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
List<Page> columnPages = list.get(i);
if (i == 0) {
String html = htmlProducer.produce(context, columnPages, pageData.getColumnMargin(), false);
sb.append(html);
} else {
String html = htmlProducer.produce(context, columnPages, pageData.getColumnMargin(), false);
sb.append(html);
}
}
} else {
List<Page> pages = report.getPages();
for (int i = 0; i < pages.size(); i++) {
Page page = pages.get(i);
if (i == 0) {
String html = htmlProducer.produce(context, page, false);
sb.append(html);
} else {
String html = htmlProducer.produce(context, page, true);
sb.append(html);
}
}
}
Map<String, String> map = new HashMap<String, String>();
map.put("html", sb.toString());
writeObjectToJson(resp, map);
}
public void loadPagePaper(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("_u");
file = decode(file);
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
ReportDefinition report = null;
if (file.equals(PREVIEW_KEY)) {
report = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (report == null) {
throw new ReportDesignException("Report data has expired.");
}
} else {
report = reportRender.getReportDefinition(file);
}
Paper paper = report.getPaper();
writeObjectToJson(resp, paper);
}
private HtmlReport loadReport(HttpServletRequest req) {
Map<String, Object> parameters = buildParameters(req);
HtmlReport htmlReport = null;
String file = req.getParameter("_u");
file = decode(file);
String pageIndex = req.getParameter("_i");
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
if (file.equals(PREVIEW_KEY)) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do preview.");
}
Report report = reportBuilder.buildReport(reportDefinition, parameters);
Map<String, ChartData> chartMap = report.getContext().getChartDataMap();
if (chartMap.size() > 0) {
CacheUtils.storeChartDataMap(chartMap);
}
htmlReport = new HtmlReport();
String html = null;
if (StringUtils.isNotBlank(pageIndex) && !pageIndex.equals("0")) {
Context context = report.getContext();
int index = Integer.valueOf(pageIndex);
SinglePageData pageData = PageBuilder.buildSinglePageData(index, report);
List<Page> pages = pageData.getPages();
if (pages.size() == 1) {
Page page = pages.get(0);
html = htmlProducer.produce(context, page, false);
} else {
html = htmlProducer.produce(context, pages, pageData.getColumnMargin(), false);
}
htmlReport.setTotalPage(pageData.getTotalPages());
htmlReport.setPageIndex(index);
} else {
html = htmlProducer.produce(report);
}
if (report.getPaper().isColumnEnabled()) {
htmlReport.setColumn(report.getPaper().getColumnCount());
}
htmlReport.setChartDatas(report.getContext().getChartDataMap().values());
htmlReport.setContent(html);
htmlReport.setTotalPage(report.getPages().size());
htmlReport.setStyle(reportDefinition.getStyle());
htmlReport.setSearchFormData(reportDefinition.buildSearchFormData(report.getContext().getDatasetMap(), parameters));
htmlReport.setReportAlign(report.getPaper().getHtmlReportAlign().name());
htmlReport.setHtmlIntervalRefreshValue(report.getPaper().getHtmlIntervalRefreshValue());
} else {
if (StringUtils.isNotBlank(pageIndex) && !pageIndex.equals("0")) {
int index = Integer.valueOf(pageIndex);
htmlReport = exportManager.exportHtml(file, req.getContextPath(), parameters, index);
} else {
htmlReport = exportManager.exportHtml(file, req.getContextPath(), parameters);
}
}
return htmlReport;
}
private String buildCustomParameters(HttpServletRequest req) {
StringBuilder sb = new StringBuilder();
Enumeration<?> enumeration = req.getParameterNames();
while (enumeration.hasMoreElements()) {
Object obj = enumeration.nextElement();
if (obj == null) {
continue;
}
String name = obj.toString();
String value = req.getParameter(name);
if (name == null || value == null || (name.startsWith("_") && !name.equals("_n"))) {
continue;
}
if (sb.length() > 0) {
sb.append("&");
}
sb.append(name);
sb.append("=");
sb.append(value);
}
return sb.toString();
}
private String buildExceptionMessage(Throwable throwable) {
Throwable root = buildRootException(throwable);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
root.printStackTrace(pw);
String trace = sw.getBuffer().toString();
trace = trace.replaceAll("\n", "<br>");
pw.close();
return trace;
}
public void setExportManager(ExportManager exportManager) {
this.exportManager = exportManager;
}
public void setReportBuilder(ReportBuilder reportBuilder) {
this.reportBuilder = reportBuilder;
}
public void setReportRender(ReportRender reportRender) {
this.reportRender = reportRender;
}
@Override
public String url() {
return "/preview";
}
}
@@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.image;
import com.bstek.ureport.cache.ResourceCache;
import com.bstek.ureport.console.ServletAction;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @author Jacky.gao
* @since 2016年6月6日
*/
public class ImageServletAction implements ServletAction {
public static final String URL = "/image";
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String key = req.getParameter("_key");
if (StringUtils.isNotBlank(key)) {
byte[] bytes = (byte[]) ResourceCache.getObject(key);
InputStream input = new ByteArrayInputStream(bytes);
OutputStream output = resp.getOutputStream();
resp.setContentType("image/png");
try {
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(output);
}
} else {
//processImage(req, resp);
}
}
@Override
public String url() {
return URL;
}
}
@@ -0,0 +1,87 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.importexcel;
import com.bstek.ureport.console.RenderPageServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.definition.ReportDefinition;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springblade.core.tool.utils.MultipartUtil;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* @author Jacky.gao
* @since 2017年5月25日
*/
public class ImportExcelServletAction extends RenderPageServletAction {
private List<ExcelParser> excelParsers = new ArrayList<ExcelParser>();
public ImportExcelServletAction() {
excelParsers.add(new HSSFExcelParser());
excelParsers.add(new XSSFExcelParser());
}
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String errorInfo;
ReportDefinition report = null;
try {
List<MultipartFile> items = MultipartUtil.extractMultipartFiles(req);
for (MultipartFile item : items) {
String fieldName = item.getName();
String name = Objects.requireNonNull(item.getOriginalFilename()).toLowerCase();
if (fieldName.equals("_excel_file") && (name.endsWith(".xls") || name.endsWith(".xlsx"))) {
InputStream inputStream = item.getInputStream();
for (ExcelParser parser : excelParsers) {
if (parser.support(name)) {
report = parser.parse(inputStream);
break;
}
}
inputStream.close();
break;
}
}
errorInfo = "请选择一个合法的Excel导入";
} catch (Exception e) {
e.printStackTrace();
errorInfo = e.getMessage();
}
Map<String, Object> result = new HashMap<String, Object>();
if (report != null) {
result.put("result", true);
TempObjectCache.putObject("classpath:template/template.ureport.xml", report);
} else {
result.put("result", false);
if (errorInfo != null) {
result.put("errorInfo", errorInfo);
}
}
writeObjectToJson(resp, result);
}
@Override
public String url() {
return "/import";
}
}
@@ -0,0 +1,144 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.pdf;
import com.bstek.ureport.build.ReportBuilder;
import com.bstek.ureport.console.BaseServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.Paper;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.export.ExportConfigure;
import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.ReportRender;
import com.bstek.ureport.export.pdf.PdfProducer;
import com.bstek.ureport.model.Report;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年3月20日
*/
public class ExportPdfServletAction extends BaseServletAction {
private ReportBuilder reportBuilder;
private ExportManager exportManager;
private ReportRender reportRender;
private PdfProducer pdfProducer = new PdfProducer();
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
} else {
buildPdf(req, resp, false);
}
}
public void show(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
buildPdf(req, resp, true);
}
public void buildPdf(HttpServletRequest req, HttpServletResponse resp, boolean forPrint) throws IOException {
String file = req.getParameter("_u");
file = decode(file);
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
OutputStream outputStream = null;
try {
String fileName = req.getParameter("_n");
fileName = buildDownloadFileName(file, fileName, ".pdf");
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
if (forPrint) {
resp.setContentType("application/pdf");
resp.setHeader("Content-Disposition", "inline;filename=\"" + fileName + "\"");
} else {
resp.setContentType("application/octet-stream;charset=ISO8859-1");
resp.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
}
outputStream = resp.getOutputStream();
Map<String, Object> parameters = buildParameters(req);
if (file.equals(PREVIEW_KEY)) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export pdf.");
}
Report report = reportBuilder.buildReport(reportDefinition, parameters);
pdfProducer.produce(report, outputStream);
} else {
ExportConfigure configure = new ExportConfigureImpl(file, parameters, outputStream);
exportManager.exportPdf(configure);
}
} catch (Exception ex) {
throw new ReportException(ex);
} finally {
outputStream.flush();
outputStream.close();
}
}
public void newPaging(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String file = req.getParameter("_u");
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
Report report = null;
Map<String, Object> parameters = buildParameters(req);
if (file.equals(PREVIEW_KEY)) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export pdf.");
}
report = reportBuilder.buildReport(reportDefinition, parameters);
} else {
ReportDefinition reportDefinition = reportRender.getReportDefinition(file);
report = reportRender.render(reportDefinition, parameters);
}
String paper = req.getParameter("_paper");
ObjectMapper mapper = new ObjectMapper();
Paper newPaper = mapper.readValue(paper, Paper.class);
report.rePaging(newPaper);
}
public void setReportRender(ReportRender reportRender) {
this.reportRender = reportRender;
}
public void setExportManager(ExportManager exportManager) {
this.exportManager = exportManager;
}
public void setReportBuilder(ReportBuilder reportBuilder) {
this.reportBuilder = reportBuilder;
}
@Override
public String url() {
return "/pdf";
}
}
@@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.res;
import com.bstek.ureport.console.ServletAction;
import com.bstek.ureport.console.UReportServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @author Jacky.gao
* @since 2016年6月6日
*/
public class ResourceLoaderServletAction implements ServletAction, ApplicationContextAware {
public static final String URL = "/res";
private ApplicationContext applicationContext;
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getContextPath() + UReportServlet.URL + URL;
String uri = req.getRequestURI();
String resPath = uri.substring(path.length() + 1);
String p = "classpath:" + resPath;
if (p.endsWith(".js")) {
resp.setContentType("text/javascript");
} else if (p.endsWith(".css")) {
resp.setContentType("text/css");
} else if (p.endsWith(".png")) {
resp.setContentType("image/png");
} else if (p.endsWith(".jpg")) {
resp.setContentType("image/jpeg");
} else if (p.endsWith(".svg")) {
resp.setContentType("image/svg+xml");
} else {
resp.setContentType("application/octet-stream");
}
InputStream input = applicationContext.getResource(p).getInputStream();
OutputStream output = resp.getOutputStream();
try {
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(output);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public String url() {
return URL;
}
}
@@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.console.word;
import com.bstek.ureport.build.ReportBuilder;
import com.bstek.ureport.console.BaseServletAction;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.export.ExportConfigure;
import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.word.high.WordProducer;
import com.bstek.ureport.model.Report;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年4月17日
*/
public class ExportWordServletAction extends BaseServletAction {
private ReportBuilder reportBuilder;
private ExportManager exportManager;
private WordProducer wordProducer = new WordProducer();
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = retriveMethod(req);
if (method != null) {
invokeMethod(method, req, resp);
} else {
buildWord(req, resp);
}
}
public void buildWord(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String file = req.getParameter("_u");
file = decode(file);
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
}
OutputStream outputStream = resp.getOutputStream();
try {
String fileName = req.getParameter("_n");
fileName = buildDownloadFileName(file, fileName, ".docx");
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
resp.setContentType("application/octet-stream;charset=ISO8859-1");
resp.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
Map<String, Object> parameters = buildParameters(req);
if (file.equals(PREVIEW_KEY)) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject(PREVIEW_KEY);
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export word.");
}
Report report = reportBuilder.buildReport(reportDefinition, parameters);
wordProducer.produce(report, outputStream);
} else {
ExportConfigure configure = new ExportConfigureImpl(file, parameters, outputStream);
exportManager.exportWord(configure);
}
} catch (Exception ex) {
throw new ReportException(ex);
} finally {
outputStream.flush();
outputStream.close();
}
}
public void setReportBuilder(ReportBuilder reportBuilder) {
this.reportBuilder = reportBuilder;
}
public void setExportManager(ExportManager exportManager) {
this.exportManager = exportManager;
}
@Override
public String url() {
return "/word";
}
}
@@ -0,0 +1,202 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.definition;
import com.bstek.ureport.export.pdf.font.FontBuilder;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.annotate.JsonIgnore;
import java.awt.*;
import java.io.Serializable;
/**
* @author Jacky.gao
* @since 2017年1月18日
*/
public class CellStyle implements Serializable {
private static final long serialVersionUID = 8327688051735343849L;
private String bgcolor;
private String forecolor;
private int fontSize;
private String fontFamily;
private String format;
private float lineHeight;
private Alignment align;
private Alignment valign;
private Boolean bold;
private Boolean italic;
private Boolean underline;
private Boolean wrapCompute;
private Border leftBorder;
private Border rightBorder;
private Border topBorder;
private Border bottomBorder;
private Font font;
public Border getLeftBorder() {
return leftBorder;
}
public void setLeftBorder(Border leftBorder) {
this.leftBorder = leftBorder;
}
public Border getRightBorder() {
return rightBorder;
}
public void setRightBorder(Border rightBorder) {
this.rightBorder = rightBorder;
}
public Border getTopBorder() {
return topBorder;
}
public void setTopBorder(Border topBorder) {
this.topBorder = topBorder;
}
public Border getBottomBorder() {
return bottomBorder;
}
public void setBottomBorder(Border bottomBorder) {
this.bottomBorder = bottomBorder;
}
public String getBgcolor() {
return bgcolor;
}
public void setBgcolor(String bgcolor) {
this.bgcolor = bgcolor;
}
public String getForecolor() {
return forecolor;
}
public void setForecolor(String forecolor) {
this.forecolor = forecolor;
}
public int getFontSize() {
return fontSize;
}
public void setFontSize(int fontSize) {
this.fontSize = fontSize;
}
public String getFontFamily() {
return fontFamily;
}
public void setFontFamily(String fontFamily) {
this.fontFamily = fontFamily;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public Alignment getAlign() {
return align;
}
public void setAlign(Alignment align) {
this.align = align;
}
public Alignment getValign() {
return valign;
}
public void setValign(Alignment valign) {
this.valign = valign;
}
public Boolean getBold() {
return bold;
}
public void setBold(Boolean bold) {
this.bold = bold;
}
public Boolean getItalic() {
return italic;
}
public void setItalic(Boolean italic) {
this.italic = italic;
}
public Boolean getUnderline() {
return underline;
}
public void setUnderline(Boolean underline) {
this.underline = underline;
}
public Boolean getWrapCompute() {
return wrapCompute;
}
public void setWrapCompute(Boolean wrapCompute) {
this.wrapCompute = wrapCompute;
}
public void setFont(Font font) {
this.font = font;
}
public float getLineHeight() {
return lineHeight;
}
public void setLineHeight(float lineHeight) {
this.lineHeight = lineHeight;
}
@JsonIgnore
public Font getFont() {
if (this.font == null) {
int fontStyle = Font.PLAIN;
if ((bold != null && bold) && (italic != null && italic)) {
fontStyle = Font.BOLD | Font.ITALIC;
} else if (bold != null && bold) {
fontStyle = Font.BOLD;
} else if (italic != null && italic) {
fontStyle = Font.ITALIC;
}
String fontName = fontFamily;
if (StringUtils.isBlank(fontName)) {
fontName = "宋体";
}
this.font = FontBuilder.getAwtFont(fontName, fontStyle, (float) fontSize);
}
return this.font;
}
}
@@ -0,0 +1,390 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.excel.high;
import com.bstek.ureport.definition.Alignment;
import com.bstek.ureport.definition.Border;
import com.bstek.ureport.definition.CellStyle;
import com.bstek.ureport.model.Cell;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import java.util.HashMap;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年11月3日
*/
public class CellStyleContext {
private Map<String, XSSFCellStyle> styleMap = new HashMap<String, XSSFCellStyle>();
public XSSFCellStyle produceXSSFCellStyle(SXSSFWorkbook wb, Cell cell) {
String name = cell.getName();
if (cell.getCustomCellStyle() == null && cell.getRow().getCustomCellStyle() == null) {
if (styleMap.containsKey(name)) {
return styleMap.get(name);
} else {
XSSFCellStyle cellStyle = createNewCellStyle(wb, cell);
styleMap.put(name, cellStyle);
return cellStyle;
}
} else {
String styleId = name + "=>" + buildStyleId(cell);
if (styleMap.containsKey(styleId)) {
return styleMap.get(styleId);
} else {
XSSFCellStyle cellStyle = createNewCellStyle(wb, cell);
styleMap.put(styleId, cellStyle);
return cellStyle;
}
}
}
private XSSFCellStyle createNewCellStyle(SXSSFWorkbook wb, Cell cell) {
CellStyle cellStyle = cell.getCellStyle();
CellStyle customStyle = cell.getCustomCellStyle();
CellStyle rowStyle = cell.getRow().getCustomCellStyle();
CellStyle colStyle = cell.getColumn().getCustomCellStyle();
XSSFCellStyle style = (XSSFCellStyle) wb.createCellStyle();
style.setWrapText(true);
String bgcolor = cellStyle.getBgcolor();
if (customStyle != null && StringUtils.isNotBlank(customStyle.getBgcolor())) {
bgcolor = customStyle.getBgcolor();
}
if (rowStyle != null && StringUtils.isNotBlank(rowStyle.getBgcolor())) {
bgcolor = rowStyle.getBgcolor();
}
if (colStyle != null && StringUtils.isNotBlank(colStyle.getBgcolor())) {
bgcolor = colStyle.getBgcolor();
}
if (StringUtils.isNotEmpty(bgcolor)) {
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(buildXSSFColor(bgcolor));
}
Border topBorder = cellStyle.getTopBorder();
if (customStyle != null && customStyle.getTopBorder() != null) {
topBorder = customStyle.getTopBorder();
}
if (topBorder != null) {
BorderStyle borderStyle = getBorderStyle(topBorder);
XSSFColor borderColor = buildXSSFColor(topBorder.getColor());
style.setTopBorderColor(borderColor);
style.setBorderTop(borderStyle);
}
Border bottomBorder = cellStyle.getBottomBorder();
if (customStyle != null && customStyle.getBottomBorder() != null) {
bottomBorder = customStyle.getBottomBorder();
}
if (bottomBorder != null) {
BorderStyle borderStyle = getBorderStyle(bottomBorder);
XSSFColor borderColor = buildXSSFColor(bottomBorder.getColor());
style.setBottomBorderColor(borderColor);
style.setBorderBottom(borderStyle);
}
Border leftBorder = cellStyle.getLeftBorder();
if (customStyle != null && customStyle.getLeftBorder() != null) {
leftBorder = customStyle.getLeftBorder();
}
if (leftBorder != null) {
BorderStyle borderStyle = getBorderStyle(leftBorder);
XSSFColor borderColor = buildXSSFColor(leftBorder.getColor());
style.setLeftBorderColor(borderColor);
style.setBorderLeft(borderStyle);
}
Border rightBorder = cellStyle.getRightBorder();
if (customStyle != null && customStyle.getRightBorder() != null) {
rightBorder = customStyle.getRightBorder();
}
if (rightBorder != null) {
BorderStyle borderStyle = getBorderStyle(rightBorder);
XSSFColor borderColor = buildXSSFColor(rightBorder.getColor());
style.setRightBorderColor(borderColor);
style.setBorderRight(borderStyle);
}
Alignment align = cellStyle.getAlign();
if (customStyle != null && customStyle.getAlign() != null) {
align = customStyle.getAlign();
}
if (rowStyle != null && rowStyle.getAlign() != null) {
align = rowStyle.getAlign();
}
if (colStyle != null && colStyle.getAlign() != null) {
align = colStyle.getAlign();
}
if (align != null) {
if (align.equals(Alignment.left)) {
style.setAlignment(HorizontalAlignment.LEFT);
} else if (align.equals(Alignment.center)) {
style.setAlignment(HorizontalAlignment.CENTER);
} else if (align.equals(Alignment.right)) {
style.setAlignment(HorizontalAlignment.RIGHT);
}
}
Alignment valign = cellStyle.getValign();
if (customStyle != null && customStyle.getValign() != null) {
valign = customStyle.getValign();
}
if (rowStyle != null && rowStyle.getValign() != null) {
valign = rowStyle.getValign();
}
if (colStyle != null && colStyle.getValign() != null) {
valign = colStyle.getValign();
}
if (valign != null) {
if (valign.equals(Alignment.top)) {
style.setVerticalAlignment(VerticalAlignment.TOP);
} else if (valign.equals(Alignment.middle)) {
style.setVerticalAlignment(VerticalAlignment.CENTER);
} else if (valign.equals(Alignment.bottom)) {
style.setVerticalAlignment(VerticalAlignment.BOTTOM);
}
}
XSSFFont font = (XSSFFont) wb.createFont();
int fontSize = cellStyle.getFontSize();
if (customStyle != null && customStyle.getFontSize() > 0) {
fontSize = customStyle.getFontSize();
}
if (rowStyle != null && rowStyle.getFontSize() > 0) {
fontSize = rowStyle.getFontSize();
}
if (colStyle != null && colStyle.getFontSize() > 0) {
fontSize = colStyle.getFontSize();
}
font.setFontHeight(fontSize);
Boolean bold = cellStyle.getBold();
if (customStyle != null && customStyle.getBold() != null) {
bold = customStyle.getBold();
}
if (rowStyle != null && rowStyle.getBold() != null) {
bold = rowStyle.getBold();
}
if (colStyle != null && colStyle.getBold() != null) {
bold = colStyle.getBold();
}
if (bold != null) {
font.setBold(bold);
}
Boolean italic = cellStyle.getItalic();
if (customStyle != null && customStyle.getItalic() != null) {
italic = customStyle.getItalic();
}
if (rowStyle != null && rowStyle.getItalic() != null) {
italic = rowStyle.getItalic();
}
if (colStyle != null && colStyle.getItalic() != null) {
italic = colStyle.getItalic();
}
if (italic != null) {
font.setItalic(italic);
}
Boolean underline = cellStyle.getUnderline();
if (customStyle != null && customStyle.getUnderline() != null) {
underline = customStyle.getUnderline();
}
if (rowStyle != null && rowStyle.getUnderline() != null) {
underline = rowStyle.getUnderline();
}
if (colStyle != null && colStyle.getUnderline() != null) {
underline = colStyle.getUnderline();
}
if (underline != null && underline) {
font.setUnderline((byte) 1);
}
String forecolor = cellStyle.getForecolor();
if (customStyle != null && customStyle.getForecolor() != null) {
forecolor = customStyle.getForecolor();
}
if (rowStyle != null && rowStyle.getForecolor() != null) {
forecolor = rowStyle.getForecolor();
}
if (colStyle != null && colStyle.getForecolor() != null) {
forecolor = colStyle.getForecolor();
}
if (StringUtils.isEmpty(forecolor)) {
forecolor = "0,0,0";
}
font.setColor(buildXSSFColor(forecolor));
String fontFamily = cellStyle.getFontFamily();
if (customStyle != null && customStyle.getFontFamily() != null) {
fontFamily = customStyle.getFontFamily();
}
if (rowStyle != null && rowStyle.getFontFamily() != null) {
fontFamily = rowStyle.getFontFamily();
}
if (colStyle != null && colStyle.getFontFamily() != null) {
fontFamily = colStyle.getFontFamily();
}
if (fontFamily != null) {
font.setFontName(fontFamily);
}
style.setFont(font);
return style;
}
private BorderStyle getBorderStyle(Border border) {
if (border.getStyle().equals(com.bstek.ureport.definition.BorderStyle.solid)) {
return BorderStyle.THIN;
} else if (border.getStyle().equals(com.bstek.ureport.definition.BorderStyle.dashed)) {
return BorderStyle.DASHED;
} else if (border.getStyle().equals(com.bstek.ureport.definition.BorderStyle.doublesolid)) {
return BorderStyle.DOUBLE;
}
return null;
}
private XSSFColor buildXSSFColor(String colorStr) {
String[] color = colorStr.split(",");
byte[] rgb = new byte[]{
(byte) Integer.parseInt(color[0]),
(byte) Integer.parseInt(color[1]),
(byte) Integer.parseInt(color[2])
};
XSSFColor xssfColor = new XSSFColor(rgb, null);
return xssfColor;
}
private String buildStyleId(Cell cell) {
CellStyle customStyle = cell.getCustomCellStyle();
CellStyle rowStyle = cell.getRow().getCustomCellStyle();
CellStyle colStyle = cell.getColumn().getCustomCellStyle();
StringBuffer sb = new StringBuffer();
String bgcolor = customStyle != null ? customStyle.getBgcolor() : null;
if (rowStyle != null && StringUtils.isNotBlank(rowStyle.getBgcolor())) {
bgcolor = rowStyle.getBgcolor();
}
if (colStyle != null && StringUtils.isNotBlank(colStyle.getBgcolor())) {
bgcolor = colStyle.getBgcolor();
}
if (StringUtils.isNotEmpty(bgcolor)) {
sb.append("bgcolor:" + bgcolor);
}
Border topBorder = customStyle != null ? customStyle.getTopBorder() : null;
if (topBorder != null) {
sb.append("topborder:" + buildBorderStyleId(topBorder));
}
Border bottomBorder = customStyle != null ? customStyle.getBottomBorder() : null;
if (bottomBorder != null) {
sb.append("bottomborder:" + buildBorderStyleId(bottomBorder));
}
Border leftBorder = customStyle != null ? customStyle.getLeftBorder() : null;
if (leftBorder != null) {
sb.append("leftborder:" + buildBorderStyleId(leftBorder));
}
Border rightBorder = customStyle != null ? customStyle.getRightBorder() : null;
if (rightBorder != null) {
sb.append("rightborder:" + buildBorderStyleId(rightBorder));
}
Alignment align = customStyle != null ? customStyle.getAlign() : null;
if (rowStyle != null && rowStyle.getAlign() != null) {
align = rowStyle.getAlign();
}
if (colStyle != null && colStyle.getAlign() != null) {
align = colStyle.getAlign();
}
if (align != null) {
if (align.equals(Alignment.left)) {
sb.append("align:" + HorizontalAlignment.LEFT.name());
} else if (align.equals(Alignment.center)) {
sb.append("align:" + HorizontalAlignment.CENTER.name());
} else if (align.equals(Alignment.right)) {
sb.append("align:" + HorizontalAlignment.RIGHT.name());
}
}
Alignment valign = customStyle != null ? customStyle.getValign() : null;
if (rowStyle != null && rowStyle.getValign() != null) {
valign = rowStyle.getValign();
}
if (colStyle != null && colStyle.getValign() != null) {
valign = colStyle.getValign();
}
if (valign != null) {
if (valign.equals(Alignment.top)) {
sb.append("valign:" + VerticalAlignment.TOP.name());
} else if (valign.equals(Alignment.middle)) {
sb.append("valign:" + VerticalAlignment.CENTER.name());
} else if (valign.equals(Alignment.bottom)) {
sb.append("valign:" + VerticalAlignment.BOTTOM.name());
}
}
Boolean underline = customStyle != null ? customStyle.getUnderline() : null;
if (rowStyle != null && rowStyle.getUnderline() != null) {
underline = rowStyle.getUnderline();
}
if (colStyle != null && colStyle.getUnderline() != null) {
underline = colStyle.getUnderline();
}
sb.append("underline:" + underline);
Boolean bold = customStyle != null ? customStyle.getBold() : null;
if (rowStyle != null && rowStyle.getBold() != null) {
bold = rowStyle.getBold();
}
if (colStyle != null && colStyle.getBold() != null) {
bold = colStyle.getBold();
}
sb.append("bold:" + bold);
Boolean italic = customStyle != null ? customStyle.getItalic() : null;
if (rowStyle != null && rowStyle.getItalic() != null) {
italic = rowStyle.getItalic();
}
if (colStyle != null && colStyle.getItalic() != null) {
italic = colStyle.getItalic();
}
sb.append("italic:" + italic);
String forecolor = customStyle != null ? customStyle.getForecolor() : null;
if (rowStyle != null && rowStyle.getForecolor() != null) {
forecolor = rowStyle.getForecolor();
}
if (colStyle != null && colStyle.getForecolor() != null) {
forecolor = colStyle.getForecolor();
}
sb.append("forecolor:" + forecolor);
String font = customStyle != null ? customStyle.getFontFamily() : null;
if (rowStyle != null && rowStyle.getFontFamily() != null) {
font = rowStyle.getFontFamily();
}
if (colStyle != null && colStyle.getFontFamily() != null) {
font = colStyle.getFontFamily();
}
sb.append("font:" + font);
int fontSize = customStyle != null ? customStyle.getFontSize() : 0;
if (rowStyle != null && rowStyle.getFontSize() > 0) {
fontSize = rowStyle.getFontSize();
}
if (colStyle != null && colStyle.getFontSize() > 0) {
fontSize = colStyle.getFontSize();
}
sb.append("font-size:" + fontSize);
return sb.toString();
}
private String buildBorderStyleId(Border border) {
StringBuilder sb = new StringBuilder();
if (border.getStyle() != null) {
sb.append("border-style:" + border.getStyle().name());
}
sb.append("border-color:" + border.getColor());
sb.append("border-width:" + border.getWidth());
return sb.toString();
}
}
@@ -0,0 +1,255 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.excel.high.builder;
import com.bstek.ureport.Utils;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.definition.Paper;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.excel.high.CellStyleContext;
import com.bstek.ureport.model.Column;
import com.bstek.ureport.model.Image;
import com.bstek.ureport.model.Report;
import com.bstek.ureport.model.Row;
import com.bstek.ureport.utils.ImageUtils;
import com.bstek.ureport.utils.UnitUtils;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年8月10日
*/
public class ExcelBuilderDirect extends ExcelBuilder {
public void build(Report report, OutputStream outputStream) {
CellStyleContext cellStyleContext = new CellStyleContext();
SXSSFWorkbook wb = new SXSSFWorkbook(100000);
CreationHelper creationHelper = wb.getCreationHelper();
Paper paper = report.getPaper();
try {
List<Column> columns = report.getColumns();
Map<Row, Map<Column, com.bstek.ureport.model.Cell>> cellMap = report.getRowColCellMap();
int columnSize = columns.size();
Sheet sheet = createSheet(wb, paper, null);
Drawing<?> drawing = sheet.createDrawingPatriarch();
List<Row> rows = report.getRows();
int rowNumber = 0;
for (Row r : rows) {
int realHeight = r.getRealHeight();
if (realHeight < 1) {
continue;
}
if (r.isForPaging()) {
return;
}
org.apache.poi.ss.usermodel.Row row = sheet.getRow(rowNumber);
if (row == null) {
row = sheet.createRow(rowNumber);
}
Map<Column, com.bstek.ureport.model.Cell> colCell = cellMap.get(r);
int skipCol = 0;
for (int i = 0; i < columnSize; i++) {
Column col = columns.get(i);
int w = col.getWidth();
if (w < 1) {
skipCol++;
continue;
}
double colWidth = UnitUtils.pointToPixel(w) * 37.5;
int colNum = i - skipCol;
sheet.setColumnWidth(colNum, (short) colWidth);
Cell cell = row.getCell(colNum);
if (cell != null) {
continue;
}
cell = row.createCell(colNum);
com.bstek.ureport.model.Cell cellInfo = null;
if (colCell != null) {
cellInfo = colCell.get(col);
}
if (cellInfo == null) {
continue;
}
if (cellInfo.isForPaging()) {
continue;
}
XSSFCellStyle style = cellStyleContext.produceXSSFCellStyle(wb, cellInfo);
int colSpan = cellInfo.getColSpan();
int rowSpan = cellInfo.getRowSpan();
int rowStart = rowNumber;
int rowEnd = rowSpan;
if (rowSpan == 0) {
rowEnd++;
}
rowEnd += rowNumber;
int colStart = i;
int colEnd = colSpan;
if (colSpan == 0) {
colEnd++;
}
colEnd += i;
for (int j = rowStart; j < rowEnd; j++) {
org.apache.poi.ss.usermodel.Row rr = sheet.getRow(j);
if (rr == null) {
rr = sheet.createRow(j);
}
for (int c = colStart; c < colEnd; c++) {
Cell cc = rr.getCell(c - skipCol);
if (cc == null) {
cc = rr.createCell(c - skipCol);
}
cc.setCellStyle(style);
}
}
if (colSpan > 0 || rowSpan > 0) {
if (rowSpan > 0) {
rowSpan--;
}
if (colSpan > 0) {
colSpan--;
}
CellRangeAddress cellRegion = new CellRangeAddress(rowNumber, (rowNumber + rowSpan), i - skipCol, (i - skipCol + colSpan));
sheet.addMergedRegion(cellRegion);
}
Object obj = cellInfo.getFormatData();
if (obj != null) {
if (obj instanceof String) {
cell.setCellValue((String) obj);
} else if (obj instanceof Number) {
BigDecimal bigDecimal = Utils.toBigDecimal(obj);
cell.setCellValue(bigDecimal.doubleValue());
} else if (obj instanceof Boolean) {
cell.setCellValue((Boolean) obj);
} else if (obj instanceof Image) {
Image img = (Image) obj;
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
int leftMargin = 0, topMargin = 0;
int wholeWidth = getWholeWidth(columns, i, cellInfo.getColSpan());
int wholeHeight = getWholeHeight(rows, rowNumber, cellInfo.getRowSpan());
HorizontalAlignment align = style.getAlignment();
if (align.equals(HorizontalAlignment.CENTER)) {
leftMargin = (wholeWidth - width) / 2;
} else if (align.equals(HorizontalAlignment.RIGHT)) {
leftMargin = wholeWidth - width;
}
VerticalAlignment valign = style.getVerticalAlignment();
if (valign.equals(VerticalAlignment.CENTER)) {
topMargin = (wholeHeight - height) / 2;
} else if (valign.equals(VerticalAlignment.BOTTOM)) {
topMargin = wholeHeight - height;
}
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(leftMargin * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(topMargin * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
} else if (obj instanceof ChartData) {
ChartData chartData = (ChartData) obj;
String base64Data = chartData.retriveBase64Data();
if (base64Data != null) {
Image img = new Image(base64Data, chartData.getWidth(), chartData.getHeight());
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
int leftMargin = 0, topMargin = 0;
int wholeWidth = getWholeWidth(columns, i, cellInfo.getColSpan());
int wholeHeight = getWholeHeight(rows, rowNumber, cellInfo.getRowSpan());
HorizontalAlignment align = style.getAlignment();
if (align.equals(HorizontalAlignment.CENTER)) {
leftMargin = (wholeWidth - width) / 2;
} else if (align.equals(HorizontalAlignment.RIGHT)) {
leftMargin = wholeWidth - width;
}
VerticalAlignment valign = style.getVerticalAlignment();
if (valign.equals(VerticalAlignment.CENTER)) {
topMargin = (wholeHeight - height) / 2;
} else if (valign.equals(VerticalAlignment.BOTTOM)) {
topMargin = wholeHeight - height;
}
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(leftMargin * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(topMargin * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
} else if (obj instanceof Date) {
cell.setCellValue((Date) obj);
}
}
}
row.setHeight((short) UnitUtils.pointToTwip(r.getRealHeight()));
rowNumber++;
}
sheet.setRowBreak(rowNumber - 1);
wb.write(outputStream);
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
wb.dispose();
}
}
}
@@ -0,0 +1,255 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.excel.high.builder;
import com.bstek.ureport.Utils;
import com.bstek.ureport.build.paging.Page;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.definition.Paper;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.excel.high.CellStyleContext;
import com.bstek.ureport.model.Column;
import com.bstek.ureport.model.Image;
import com.bstek.ureport.model.Report;
import com.bstek.ureport.model.Row;
import com.bstek.ureport.utils.ImageUtils;
import com.bstek.ureport.utils.UnitUtils;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年8月10日
*/
public class ExcelBuilderWithPaging extends ExcelBuilder {
public void build(Report report, OutputStream outputStream, boolean withSheet) {
CellStyleContext cellStyleContext = new CellStyleContext();
SXSSFWorkbook wb = new SXSSFWorkbook(1000);
CreationHelper creationHelper = wb.getCreationHelper();
Paper paper = report.getPaper();
try {
List<Column> columns = report.getColumns();
Map<Row, Map<Column, com.bstek.ureport.model.Cell>> cellMap = report.getRowColCellMap();
int columnSize = columns.size();
List<Page> pages = report.getPages();
int rowNumber = 0, pageIndex = 1;
Sheet sheet = null;
for (Page page : pages) {
if (withSheet) {
sheet = createSheet(wb, paper, "" + pageIndex + "");
rowNumber = 0;
} else if (sheet == null) {
sheet = createSheet(wb, paper, null);
}
pageIndex++;
Drawing<?> drawing = sheet.createDrawingPatriarch();
List<Row> rows = page.getRows();
for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
Row r = rows.get(rowIndex);
org.apache.poi.ss.usermodel.Row row = sheet.getRow(rowNumber);
if (row == null) {
row = sheet.createRow(rowNumber);
}
Map<Column, com.bstek.ureport.model.Cell> colCell = cellMap.get(r);
int skipCol = 0;
for (int i = 0; i < columnSize; i++) {
Column col = columns.get(i);
int w = col.getWidth();
if (w < 1) {
skipCol++;
continue;
}
int colNum = i - skipCol;
double colWidth = UnitUtils.pointToPixel(w) * 37.5;
sheet.setColumnWidth(colNum, (short) colWidth);
Cell cell = row.getCell(colNum);
if (cell != null) {
continue;
}
cell = row.createCell(colNum);
com.bstek.ureport.model.Cell cellInfo = null;
if (colCell != null) {
cellInfo = colCell.get(col);
}
if (cellInfo == null) {
continue;
}
XSSFCellStyle style = cellStyleContext.produceXSSFCellStyle(wb, cellInfo);
int colSpan = cellInfo.getColSpan();
int rowSpan = cellInfo.getPageRowSpan();
int rowStart = rowNumber;
int rowEnd = rowSpan;
if (rowSpan == 0) {
rowEnd++;
}
rowEnd += rowNumber;
int colStart = i;
int colEnd = colSpan;
if (colSpan == 0) {
colEnd++;
}
colEnd += i;
for (int j = rowStart; j < rowEnd; j++) {
org.apache.poi.ss.usermodel.Row rr = sheet.getRow(j);
if (rr == null) {
rr = sheet.createRow(j);
}
for (int c = colStart; c < colEnd; c++) {
Cell cc = rr.getCell(c - skipCol);
if (cc == null) {
cc = rr.createCell(c - skipCol);
}
cc.setCellStyle(style);
}
}
if (colSpan > 0 || rowSpan > 0) {
if (rowSpan > 0) {
rowSpan--;
}
if (colSpan > 0) {
colSpan--;
}
CellRangeAddress cellRegion = new CellRangeAddress(rowNumber, (rowNumber + rowSpan), i - skipCol, (i - skipCol + colSpan));
sheet.addMergedRegion(cellRegion);
}
Object obj = cellInfo.getFormatData();
if (obj != null) {
if (obj instanceof String) {
cell.setCellValue((String) obj);
} else if (obj instanceof Number) {
BigDecimal bigDecimal = Utils.toBigDecimal(obj);
cell.setCellValue(bigDecimal.floatValue());
} else if (obj instanceof Boolean) {
cell.setCellValue((Boolean) obj);
} else if (obj instanceof Image) {
Image img = (Image) obj;
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
int leftMargin = 0, topMargin = 0;
int wholeWidth = getWholeWidth(columns, i, cellInfo.getColSpan());
int wholeHeight = getWholeHeight(rows, rowIndex, cellInfo.getRowSpan());
HorizontalAlignment align = style.getAlignment();
if (align.equals(HorizontalAlignment.CENTER)) {
leftMargin = (wholeWidth - width) / 2;
} else if (align.equals(HorizontalAlignment.RIGHT)) {
leftMargin = wholeWidth - width;
}
VerticalAlignment valign = style.getVerticalAlignment();
if (valign.equals(VerticalAlignment.CENTER)) {
topMargin = (wholeHeight - height) / 2;
} else if (valign.equals(VerticalAlignment.BOTTOM)) {
topMargin = wholeHeight - height;
}
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(leftMargin * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(topMargin * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
} else if (obj instanceof ChartData) {
ChartData chartData = (ChartData) obj;
String base64Data = chartData.retriveBase64Data();
if (base64Data != null) {
Image img = new Image(base64Data, chartData.getWidth(), chartData.getHeight());
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
int leftMargin = 0, topMargin = 0;
int wholeWidth = getWholeWidth(columns, i, cellInfo.getColSpan());
int wholeHeight = getWholeHeight(rows, rowIndex, cellInfo.getRowSpan());
HorizontalAlignment align = style.getAlignment();
if (align.equals(HorizontalAlignment.CENTER)) {
leftMargin = (wholeWidth - width) / 2;
} else if (align.equals(HorizontalAlignment.RIGHT)) {
leftMargin = wholeWidth - width;
}
VerticalAlignment valign = style.getVerticalAlignment();
if (valign.equals(VerticalAlignment.CENTER)) {
topMargin = (wholeHeight - height) / 2;
} else if (valign.equals(VerticalAlignment.BOTTOM)) {
topMargin = wholeHeight - height;
}
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(leftMargin * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(topMargin * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
} else if (obj instanceof Date) {
cell.setCellValue((Date) obj);
}
}
}
row.setHeight((short) UnitUtils.pointToTwip(r.getHeight()));
rowNumber++;
}
sheet.setRowBreak(rowNumber - 1);
}
wb.write(outputStream);
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
wb.dispose();
}
}
}
@@ -0,0 +1,504 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.excel.low;
import com.bstek.ureport.Utils;
import com.bstek.ureport.build.paging.Page;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.definition.Orientation;
import com.bstek.ureport.definition.Paper;
import com.bstek.ureport.definition.PaperType;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.model.Column;
import com.bstek.ureport.model.Image;
import com.bstek.ureport.model.Report;
import com.bstek.ureport.model.Row;
import com.bstek.ureport.utils.ImageUtils;
import com.bstek.ureport.utils.UnitUtils;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年7月3日
*/
public class Excel97Producer {
public void produceWithPaging(Report report, OutputStream outputStream) {
doProduce(report, outputStream, true, false);
}
public void produce(Report report, OutputStream outputStream) {
doProduce(report, outputStream, false, false);
}
public void produceWithSheet(Report report, OutputStream outputStream) {
doProduce(report, outputStream, true, true);
}
private void doProduce(Report report, OutputStream outputStream, boolean withPaging, boolean withSheet) {
CellStyleContext cellStyleContext = new CellStyleContext();
HSSFWorkbook wb = new HSSFWorkbook();
CreationHelper creationHelper = wb.getCreationHelper();
Paper paper = report.getPaper();
try {
List<Column> columns = report.getColumns();
Map<Row, Map<Column, com.bstek.ureport.model.Cell>> cellMap = report.getRowColCellMap();
int columnSize = columns.size();
if (withPaging) {
List<Page> pages = report.getPages();
int rowNumber = 0, pageIndex = 1;
Sheet sheet = null;
for (Page page : pages) {
if (withSheet) {
sheet = createSheet(wb, paper, "" + pageIndex + "");
rowNumber = 0;
} else if (sheet == null) {
sheet = createSheet(wb, paper, null);
}
pageIndex++;
Drawing<?> drawing = sheet.createDrawingPatriarch();
List<Row> rows = page.getRows();
for (Row r : rows) {
org.apache.poi.ss.usermodel.Row row = sheet.getRow(rowNumber);
if (row == null) {
row = sheet.createRow(rowNumber);
}
Map<Column, com.bstek.ureport.model.Cell> colCell = cellMap.get(r);
for (int i = 0; i < columnSize; i++) {
Column col = columns.get(i);
int w = col.getWidth();
if (w < 1) {
continue;
}
double colWidth = UnitUtils.pointToPixel(w) * 37.5;
sheet.setColumnWidth(i, (short) colWidth);
Cell cell = row.getCell(i);
if (cell != null) {
continue;
}
cell = row.createCell(i);
com.bstek.ureport.model.Cell cellInfo = colCell.get(col);
if (cellInfo == null) {
continue;
}
HSSFCellStyle style = cellStyleContext.produceXSSFCellStyle(wb, cellInfo);
int colSpan = cellInfo.getColSpan();
int rowSpan = cellInfo.getPageRowSpan();
int rowStart = rowNumber;
int rowEnd = rowSpan;
if (rowSpan == 0) {
rowEnd++;
}
rowEnd += rowNumber;
int colStart = i;
int colEnd = colSpan;
if (colSpan == 0) {
colEnd++;
}
colEnd += i;
for (int j = rowStart; j < rowEnd; j++) {
org.apache.poi.ss.usermodel.Row rr = sheet.getRow(j);
if (rr == null) {
rr = sheet.createRow(j);
}
for (int c = colStart; c < colEnd; c++) {
Cell cc = rr.getCell(c);
if (cc == null) {
cc = rr.createCell(c);
}
cc.setCellStyle(style);
}
}
if (colSpan > 0 || rowSpan > 0) {
if (rowSpan > 0) {
rowSpan--;
}
if (colSpan > 0) {
colSpan--;
}
CellRangeAddress cellRegion = new CellRangeAddress(rowNumber, (rowNumber + rowSpan), i, (i + colSpan));
sheet.addMergedRegion(cellRegion);
}
Object obj = cellInfo.getFormatData();
if (obj != null) {
if (obj instanceof String) {
cell.setCellValue((String) obj);
} else if (obj instanceof Number) {
BigDecimal bigDecimal = Utils.toBigDecimal(obj);
cell.setCellValue(bigDecimal.floatValue());
} else if (obj instanceof Boolean) {
cell.setCellValue((Boolean) obj);
} else if (obj instanceof Image) {
Image img = (Image) obj;
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(0 * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(0 * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
} else if (obj instanceof ChartData) {
ChartData chartData = (ChartData) obj;
String base64Data = chartData.retriveBase64Data();
if (base64Data != null) {
Image img = new Image(base64Data, chartData.getWidth(), chartData.getHeight());
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(0 * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(0 * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
} else if (obj instanceof Date) {
cell.setCellValue((Date) obj);
}
}
}
row.setHeight((short) UnitUtils.pointToTwip(r.getHeight()));
rowNumber++;
}
sheet.setRowBreak(rowNumber - 1);
}
} else {
Sheet sheet = createSheet(wb, paper, null);
Drawing<?> drawing = sheet.createDrawingPatriarch();
List<Row> rows = report.getRows();
int rowNumber = 0;
for (Row r : rows) {
int realHeight = r.getRealHeight();
if (realHeight < 1) {
continue;
}
if (r.isForPaging()) {
return;
}
org.apache.poi.ss.usermodel.Row row = sheet.getRow(rowNumber);
if (row == null) {
row = sheet.createRow(rowNumber);
}
Map<Column, com.bstek.ureport.model.Cell> colCell = cellMap.get(r);
for (int i = 0; i < columnSize; i++) {
Column col = columns.get(i);
int w = col.getWidth();
if (w < 1) {
continue;
}
double colWidth = UnitUtils.pointToPixel(w) * 37.5;
sheet.setColumnWidth(i, (short) colWidth);
Cell cell = row.getCell(i);
if (cell != null) {
continue;
}
cell = row.createCell(i);
com.bstek.ureport.model.Cell cellInfo = colCell.get(col);
if (cellInfo == null) {
continue;
}
if (cellInfo.isForPaging()) {
continue;
}
HSSFCellStyle style = cellStyleContext.produceXSSFCellStyle(wb, cellInfo);
int colSpan = cellInfo.getColSpan();
int rowSpan = cellInfo.getRowSpan();
int rowStart = rowNumber;
int rowEnd = rowSpan;
if (rowSpan == 0) {
rowEnd++;
}
rowEnd += rowNumber;
int colStart = i;
int colEnd = colSpan;
if (colSpan == 0) {
colEnd++;
}
colEnd += i;
for (int j = rowStart; j < rowEnd; j++) {
org.apache.poi.ss.usermodel.Row rr = sheet.getRow(j);
if (rr == null) {
rr = sheet.createRow(j);
}
for (int c = colStart; c < colEnd; c++) {
Cell cc = rr.getCell(c);
if (cc == null) {
cc = rr.createCell(c);
}
cc.setCellStyle(style);
}
}
if (colSpan > 0 || rowSpan > 0) {
if (rowSpan > 0) {
rowSpan--;
}
if (colSpan > 0) {
colSpan--;
}
CellRangeAddress cellRegion = new CellRangeAddress(rowNumber, (rowNumber + rowSpan), i, (i + colSpan));
sheet.addMergedRegion(cellRegion);
}
Object obj = cellInfo.getFormatData();
if (obj != null) {
if (obj instanceof String) {
cell.setCellValue((String) obj);
} else if (obj instanceof Number) {
BigDecimal bigDecimal = Utils.toBigDecimal(obj);
cell.setCellValue(bigDecimal.floatValue());
} else if (obj instanceof Boolean) {
cell.setCellValue((Boolean) obj);
} else if (obj instanceof Image) {
Image img = (Image) obj;
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(0 * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(0 * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
} else if (obj instanceof ChartData) {
ChartData chartData = (ChartData) obj;
String base64Data = chartData.retriveBase64Data();
if (base64Data != null) {
Image img = new Image(base64Data, chartData.getWidth(), chartData.getHeight());
InputStream inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(img.getBase64Data());
try {
XSSFClientAnchor anchor = (XSSFClientAnchor) creationHelper.createClientAnchor();
byte[] bytes = IOUtils.toByteArray(inputStream);
int pictureFormat = buildImageFormat(img);
int pictureIndex = wb.addPicture(bytes, pictureFormat);
anchor.setCol1(i);
anchor.setCol2(i + colSpan);
anchor.setRow1(rowNumber);
anchor.setRow2(rowNumber + rowSpan);
anchor.setDx1(0 * Units.EMU_PER_PIXEL);
anchor.setDx2(width * Units.EMU_PER_PIXEL);
anchor.setDy1(0 * Units.EMU_PER_PIXEL);
anchor.setDy2(height * Units.EMU_PER_PIXEL);
drawing.createPicture(anchor, pictureIndex);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
} else if (obj instanceof Date) {
cell.setCellValue((Date) obj);
}
}
}
row.setHeight((short) UnitUtils.pointToTwip(r.getRealHeight()));
rowNumber++;
}
sheet.setRowBreak(rowNumber - 1);
}
wb.write(outputStream);
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
try {
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private Sheet createSheet(HSSFWorkbook wb, Paper paper, String name) {
Sheet sheet = null;
if (name == null) {
sheet = wb.createSheet();
} else {
sheet = wb.createSheet(name);
}
PaperType paperType = paper.getPaperType();
HSSFPrintSetup printSetup = (HSSFPrintSetup) sheet.getPrintSetup();
Orientation orientation = paper.getOrientation();
if (orientation.equals(Orientation.landscape)) {
printSetup.setLandscape(true);
}
setupPaper(paperType, printSetup);
int leftMargin = paper.getLeftMargin();
int rightMargin = paper.getRightMargin();
int topMargin = paper.getTopMargin();
int bottomMargin = paper.getBottomMargin();
sheet.setMargin(Sheet.LeftMargin, UnitUtils.pointToInche(leftMargin));
sheet.setMargin(Sheet.RightMargin, UnitUtils.pointToInche(rightMargin));
sheet.setMargin(Sheet.TopMargin, UnitUtils.pointToInche(topMargin));
sheet.setMargin(Sheet.BottomMargin, UnitUtils.pointToInche(bottomMargin));
return sheet;
}
private int buildImageFormat(Image img) {
int type = Workbook.PICTURE_TYPE_PNG;
String path = img.getPath();
if (path == null) {
return type;
}
path = path.toLowerCase();
if (path.endsWith("jpg") || path.endsWith("jpeg")) {
type = Workbook.PICTURE_TYPE_JPEG;
}
return type;
}
private boolean setupPaper(PaperType paperType, HSSFPrintSetup printSetup) {
boolean setup = false;
switch (paperType) {
case A0:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A1:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A2:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A3:
printSetup.setPaperSize(HSSFPrintSetup.A3_PAPERSIZE);
setup = true;
break;
case A4:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
setup = true;
break;
case A5:
printSetup.setPaperSize(HSSFPrintSetup.A5_PAPERSIZE);
setup = true;
break;
case A6:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A7:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A8:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A9:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case A10:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B0:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B1:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B2:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B3:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B4:
printSetup.setPaperSize(HSSFPrintSetup.B4_PAPERSIZE);
setup = true;
break;
case B5:
printSetup.setPaperSize(HSSFPrintSetup.B5_PAPERSIZE);
setup = true;
break;
case B6:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B7:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B8:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B9:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case B10:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
case CUSTOM:
printSetup.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE);
break;
}
return setup;
}
}
@@ -0,0 +1,156 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.pdf.font;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.exception.ReportException;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.pdf.BaseFont;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.List;
/**
* @author Jacky.gao
* @since 2014年4月22日
*/
public class FontBuilder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
private static final Map<String, BaseFont> fontMap = new HashMap<String, BaseFont>();
public static final Map<String, String> fontPathMap = new HashMap<String, String>();
private static List<String> systemFontNameList = new ArrayList<String>();
public static Font getFont(String fontName, int fontSize, boolean fontBold, boolean fontItalic, boolean underLine) {
BaseFont baseFont = fontMap.get(fontName);
Font font = null;
if (baseFont != null) {
font = new Font(baseFont);
} else {
font = FontFactory.getFont(fontName);
}
font.setSize(fontSize);
int fontStyle = Font.NORMAL;
if (fontBold && fontItalic && underLine) {
fontStyle = Font.BOLD | Font.ITALIC | Font.UNDERLINE;
} else if (fontBold) {
if (fontItalic) {
fontStyle = Font.BOLD | Font.ITALIC;
} else if (underLine) {
fontStyle = Font.BOLD | Font.UNDERLINE;
} else {
fontStyle = Font.BOLD;
}
} else if (fontItalic) {
if (underLine) {
fontStyle = Font.ITALIC | Font.UNDERLINE;
} else if (fontBold) {
fontStyle = Font.ITALIC | Font.BOLD;
} else {
fontStyle = Font.ITALIC;
}
} else if (underLine) {
fontStyle = Font.UNDERLINE;
}
font.setStyle(fontStyle);
return font;
}
public static java.awt.Font getAwtFont(String fontName, int fontStyle, float size) {
if (systemFontNameList.contains(fontName)) {
return new java.awt.Font(fontName, fontStyle, (int) size);
}
String fontPath = fontPathMap.get(fontName);
if (fontPath == null) {
fontName = "宋体";
fontPath = fontPathMap.get(fontName);
if (fontPath == null) {
return null;
}
}
InputStream inputStream = null;
try {
inputStream = applicationContext.getResource(fontPath).getInputStream();
java.awt.Font font = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, inputStream);
return font.deriveFont(fontStyle, size);
} catch (Exception e) {
throw new ReportException(e);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
FontBuilder.applicationContext = applicationContext;
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = environment.getAvailableFontFamilyNames();
for (String name : fontNames) {
systemFontNameList.add(name);
}
Collection<FontRegister> fontRegisters = applicationContext.getBeansOfType(FontRegister.class).values();
for (FontRegister fontReg : fontRegisters) {
String fontName = fontReg.getFontName();
String fontPath = fontReg.getFontPath();
if (StringUtils.isEmpty(fontPath) || StringUtils.isEmpty(fontName)) {
continue;
}
try {
BaseFont baseFont = getIdentityFont(fontName, fontPath, applicationContext);
if (baseFont == null) {
throw new ReportComputeException("Font " + fontPath + " does not exist");
}
fontMap.put(fontName, baseFont);
} catch (Exception e) {
e.printStackTrace();
throw new ReportComputeException(e);
}
}
}
private BaseFont getIdentityFont(String fontFamily, String fontPath, ApplicationContext applicationContext) throws DocumentException, IOException {
if (!fontPath.startsWith(ApplicationContext.CLASSPATH_URL_PREFIX)) {
fontPath = ApplicationContext.CLASSPATH_URL_PREFIX + fontPath;
}
String fontName = fontPath;
int lastSlashPos = fontPath.lastIndexOf("/");
if (lastSlashPos != -1) {
fontName = fontPath.substring(lastSlashPos + 1, fontPath.length());
}
if (fontName.toLowerCase().endsWith(".ttc")) {
fontName = fontName + ",0";
}
InputStream inputStream = null;
try {
fontPathMap.put(fontFamily, fontPath);
inputStream = applicationContext.getResource(fontPath).getInputStream();
byte[] bytes = IOUtils.toByteArray(inputStream);
BaseFont baseFont = BaseFont.createFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, true, bytes, null);
baseFont.setSubset(true);
return baseFont;
} finally {
if (inputStream != null) inputStream.close();
}
}
}
@@ -0,0 +1,403 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.word.high;
import com.bstek.ureport.build.paging.HeaderFooter;
import com.bstek.ureport.model.Report;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Jacky.gao
* @since 2017年4月17日
*/
public class HeaderFooterBuilder {
public void build(XWPFDocument document, CTSectPr sectPr, Report report) {
//HeaderFooterDefinition headerDef=report.getHeader();
//HeaderFooterDefinition footerDef=report.getFooter();
HeaderFooter header = new HeaderFooter();
HeaderFooter footer = new HeaderFooter();
XWPFHeaderFooterPolicy headerFooterPolicy = null;
if (header != null) {
List<XWPFParagraph> list = buildXWPFParagraph(header, document);
XWPFParagraph[] newparagraphs = new XWPFParagraph[list.size()];
list.toArray(newparagraphs);
headerFooterPolicy = new XWPFHeaderFooterPolicy(document, sectPr);
headerFooterPolicy.createHeader(STHdrFtr.DEFAULT, newparagraphs);
}
if (footer != null) {
List<XWPFParagraph> list = buildXWPFParagraph(footer, document);
XWPFParagraph[] newparagraphs = new XWPFParagraph[list.size()];
list.toArray(newparagraphs);
/*if(headerFooterPolicy==null){
headerFooterPolicy = new XWPFHeaderFooterPolicy(document, sectPr);
}*/
headerFooterPolicy.createFooter(STHdrFtr.DEFAULT, newparagraphs);
}
}
private List<XWPFParagraph> buildXWPFParagraph(HeaderFooter hf, XWPFDocument document) {
CTP ctp = null;
List<XWPFParagraph> paras = new ArrayList<XWPFParagraph>();
XWPFParagraph para = null;
XWPFRun r1 = null;
String left = hf.getLeft();
String center = hf.getCenter();
String right = hf.getRight();
SimpleDateFormat dateSD = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat timeSD = new SimpleDateFormat("HH:MM:ss");
Date D = new Date();
String date = dateSD.format(D);
String time = timeSD.format(D);
if (StringUtils.isNotBlank(left)) {
ctp = CTP.Factory.newInstance();
para = new XWPFParagraph(ctp, document);
para.setAlignment(ParagraphAlignment.LEFT);
paras.add(para);
List<String> list = splitHeaderFooterContent(left);
for (int i = 0; i < list.size(); i++) {
String text = list.get(i);
if (text.equals("$[PAGE]")) {
r1 = para.createRun();
CTFldChar fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
CTText ctText = r1.getCTR().addNewInstrText();
ctText.setStringValue("PAGE \\* MERGEFORMAT");
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
} else if (text.equals("$[PAGES]")) {
r1 = para.createRun();
CTFldChar fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
CTText ctText = r1.getCTR().addNewInstrText();
ctText.setStringValue("NUMPAGES \\* MERGEFORMAT ");
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
} else if (text.equals("$[DATE]")) {
r1 = para.createRun();
r1.setText(date);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
} else if (text.equals("$[TIME]")) {
r1 = para.createRun();
r1.setText(time);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
} else {
r1 = para.createRun();
r1.setText(text);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
}
}
}
if (StringUtils.isNotBlank(center)) {
ctp = CTP.Factory.newInstance();
para = new XWPFParagraph(ctp, document);
para.setAlignment(ParagraphAlignment.CENTER);
paras.add(para);
List<String> list = splitHeaderFooterContent(center);
for (int i = 0; i < list.size(); i++) {
String text = list.get(i);
if (text.equals("$[PAGE]")) {
r1 = para.createRun();
CTFldChar fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
CTText ctText = r1.getCTR().addNewInstrText();
ctText.setStringValue("PAGE \\* MERGEFORMAT");
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
} else if (text.equals("$[PAGES]")) {
r1 = para.createRun();
CTFldChar fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
CTText ctText = r1.getCTR().addNewInstrText();
ctText.setStringValue("NUMPAGES \\* MERGEFORMAT ");
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
} else if (text.equals("$[DATE]")) {
r1 = para.createRun();
r1.setText(date);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
} else if (text.equals("$[TIME]")) {
r1 = para.createRun();
r1.setText(time);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
} else {
r1 = para.createRun();
r1.setText(text);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
}
}
}
if (StringUtils.isNotBlank(right)) {
ctp = CTP.Factory.newInstance();
para = new XWPFParagraph(ctp, document);
para.setAlignment(ParagraphAlignment.RIGHT);
paras.add(para);
List<String> list = splitHeaderFooterContent(right);
for (int i = 0; i < list.size(); i++) {
String text = list.get(i);
if (text.equals("$[PAGE]")) {
r1 = para.createRun();
CTFldChar fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
CTText ctText = r1.getCTR().addNewInstrText();
ctText.setStringValue("PAGE \\* MERGEFORMAT");
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
} else if (text.equals("$[PAGES]")) {
r1 = para.createRun();
CTFldChar fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
CTText ctText = r1.getCTR().addNewInstrText();
ctText.setStringValue("NUMPAGES \\* MERGEFORMAT ");
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
fldChar = r1.getCTR().addNewFldChar();
fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
} else if (text.equals("$[DATE]")) {
r1 = para.createRun();
r1.setText(date);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
} else if (text.equals("$[TIME]")) {
r1 = para.createRun();
r1.setText(time);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
} else {
r1 = para.createRun();
r1.setText(text);
if (hf.getFontSize() > 1) {
r1.setFontSize(hf.getFontSize());
}
String fontName = hf.getFontFamily();
if (fontName != null) {
r1.setFontFamily(fontName);
}
if (hf.isBold()) {
r1.setBold(true);
}
if (hf.isItalic()) {
r1.setItalic(true);
}
}
}
}
return paras;
}
private List<String> splitHeaderFooterContent(String info) {
Pattern pattern = Pattern.compile("\\$\\[PAGE\\]|\\$\\[PAGES\\]|\\$\\[DATE\\]|\\$\\[TIME\\]");
Matcher matcher = pattern.matcher(info);
List<String> list = new ArrayList<String>();
int start = 0;
while (matcher.find()) {
String text = matcher.group();
int pos = info.indexOf(text);
String str = info.substring(start, pos);
start = pos + text.length();
list.add(str);
list.add(text);
}
if (start < info.length()) {
list.add(info.substring(start, info.length()));
}
return list;
}
}
@@ -0,0 +1,559 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.word.high;
import com.bstek.ureport.build.paging.Page;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.definition.*;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.Producer;
import com.bstek.ureport.export.word.DxaUtils;
import com.bstek.ureport.model.*;
import com.bstek.ureport.utils.ImageUtils;
import com.bstek.ureport.utils.UnitUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年5月20日
*/
public class WordProducer implements Producer {
public static final String BEAN_ID = "ureport.wordExporter";
@Override
public void produce(Report report, OutputStream outputStream) {
XWPFDocument document = new XWPFDocument();
try {
CTSectPr sectpr = document.getDocument().getBody().addNewSectPr();
if (!sectpr.isSetPgSz()) {
sectpr.addNewPgSz();
}
CTPageSz pageSize = sectpr.getPgSz();
Paper paper = report.getPaper();
Orientation orientation = paper.getOrientation();
if (orientation.equals(Orientation.landscape)) {
pageSize.setOrient(STPageOrientation.LANDSCAPE);
pageSize.setH(DxaUtils.points2dxa(paper.getWidth()));
pageSize.setW(DxaUtils.points2dxa(paper.getHeight()));
} else {
pageSize.setOrient(STPageOrientation.PORTRAIT);
pageSize.setW(DxaUtils.points2dxa(paper.getWidth()));
pageSize.setH(DxaUtils.points2dxa(paper.getHeight()));
}
int columnCount = paper.getColumnCount();
if (paper.isColumnEnabled() && columnCount > 0) {
CTColumns cols = CTColumns.Factory.newInstance();
cols.setNum(new BigInteger(String.valueOf(columnCount)));
int columnMargin = paper.getColumnMargin();
cols.setSpace(new BigInteger(String.valueOf(DxaUtils.points2dxa(columnMargin))));
sectpr.setCols(cols);
}
CTPageMar pageMar = sectpr.addNewPgMar();
pageMar.setLeft(DxaUtils.points2dxa(paper.getLeftMargin()));
pageMar.setRight(DxaUtils.points2dxa(paper.getRightMargin()));
pageMar.setTop(DxaUtils.points2dxa(paper.getTopMargin()));
pageMar.setBottom(DxaUtils.points2dxa(paper.getBottomMargin()));
List<Column> columns = report.getColumns();
int intArr[] = buildColumnSizeAndTotalWidth(columns);
int totalColumn = intArr[0], tableWidth = intArr[1];
List<Page> pages = report.getPages();
Map<Row, Map<Column, Cell>> cellMap = report.getRowColCellMap();
int totalPages = pages.size();
int pageIndex = 1;
for (Page page : pages) {
List<Row> rows = page.getRows();
XWPFTable table = document.createTable(rows.size(), totalColumn);
table.getCTTbl().getTblPr().unsetTblBorders();
table.getCTTbl().addNewTblPr().addNewTblW().setW(DxaUtils.points2dxa(tableWidth));
for (int rowNumber = 0; rowNumber < rows.size(); rowNumber++) {
Row row = rows.get(rowNumber);
int height = row.getRealHeight();
XWPFTableRow tableRow = table.getRow(rowNumber);
tableRow.setHeight(DxaUtils.points2dxa(height));
Map<Column, Cell> colCell = cellMap.get(row);
if (colCell == null) continue;
int skipCol = 0;
for (Column col : columns) {
int width = col.getWidth();
if (width < 1) {
skipCol++;
continue;
}
int colNumber = col.getColumnNumber() - 1 - skipCol;
Cell cell = colCell.get(col);
if (cell == null) {
continue;
}
XWPFTableCell tableCell = tableRow.getCell(colNumber);
if (tableCell == null) {
continue;
}
tableCell.getCTTc().addNewTcPr().addNewTcW().setW(DxaUtils.points2dxa(width));
buildTableCellStyle(table, tableCell, cell, rowNumber, colNumber);
}
}
if (pageIndex < totalPages) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setFontSize(0);
run.addBreak(BreakType.PAGE);
}
pageIndex++;
}
document.write(outputStream);
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
try {
document.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private int[] buildColumnSizeAndTotalWidth(List<Column> columns) {
int count = 0, totalWidth = 0;
for (int i = 0; i < columns.size(); i++) {
Column col = columns.get(i);
int width = col.getWidth();
if (width < 1) {
continue;
}
count++;
totalWidth += width;
}
return new int[]{count, totalWidth};
}
private void buildTableCellStyle(XWPFTable table, XWPFTableCell tableCell, Cell cell, int rowNumber, int columnNumber) {
CellStyle style = cell.getCellStyle();
CellStyle customStyle = cell.getCustomCellStyle();
CellStyle rowStyle = cell.getRow().getCustomCellStyle();
CellStyle colStyle = cell.getColumn().getCustomCellStyle();
CTTcPr cellProperties = tableCell.getCTTc().addNewTcPr();
Border leftBorder = style.getLeftBorder();
Border rightBorder = style.getRightBorder();
Border topBorder = style.getTopBorder();
Border bottomBorder = style.getBottomBorder();
if (customStyle != null) {
if (customStyle.getLeftBorder() != null) {
leftBorder = customStyle.getLeftBorder();
}
if (customStyle.getRightBorder() != null) {
rightBorder = customStyle.getRightBorder();
}
if (customStyle.getTopBorder() != null) {
topBorder = customStyle.getTopBorder();
}
if (customStyle.getBottomBorder() != null) {
bottomBorder = customStyle.getBottomBorder();
}
}
int rowSpan = cell.getPageRowSpan();
int colSpan = cell.getColSpan();
if (style.getLeftBorder() != null) {
if (rowSpan > 0) {
int start = rowNumber;
int end = start + rowSpan;
for (int i = start; i < end; i++) {
XWPFTableCell c = table.getRow(i).getCell(columnNumber);
buildCellBorder(leftBorder, c, 1);
}
} else {
buildCellBorder(leftBorder, tableCell, 1);
}
}
if (rightBorder != null) {
int lastCol = columnNumber;
if (colSpan > 0) {
lastCol += colSpan - 1;
}
if (rowSpan > 0) {
int start = rowNumber;
int end = start + rowSpan;
for (int i = start; i < end; i++) {
XWPFTableCell c = table.getRow(i).getCell(lastCol);
buildCellBorder(style.getRightBorder(), c, 2);
}
} else {
XWPFTableCell c = table.getRow(rowNumber).getCell(lastCol);
buildCellBorder(rightBorder, c, 2);
}
}
if (topBorder != null) {
if (colSpan > 0) {
int start = columnNumber;
int end = start + colSpan;
for (int i = start; i < end; i++) {
XWPFTableCell c = table.getRow(rowNumber).getCell(i);
buildCellBorder(topBorder, c, 3);
}
} else {
buildCellBorder(topBorder, tableCell, 3);
}
}
if (bottomBorder != null) {
int lastRow = rowNumber;
if (rowSpan > 0) {
lastRow += rowSpan - 1;
}
if (colSpan > 0) {
int start = columnNumber;
int end = start + colSpan;
for (int i = start; i < end; i++) {
XWPFTableCell c = table.getRow(lastRow).getCell(i);
buildCellBorder(bottomBorder, c, 4);
}
} else {
XWPFTableCell c = table.getRow(lastRow).getCell(columnNumber);
buildCellBorder(bottomBorder, c, 4);
}
}
List<XWPFParagraph> paras = tableCell.getParagraphs();
XWPFParagraph para = null;
if (paras != null && paras.size() > 0) {
para = paras.get(0);
} else {
para = tableCell.addParagraph();
}
List<XWPFRun> runs = para.getRuns();
XWPFRun run = null;
if (runs != null && runs.size() > 0) {
run = runs.get(0);
} else {
run = para.createRun();
}
Object value = cell.getFormatData();
if (value instanceof String) {
String text = value.toString();
if (text.contains("\n")) {
String[] line = text.split("\n");
run.setText(line[0], 0);
for (int i = 1; i < line.length; i++) {
run.addBreak();
run.setText(line[i], i);
}
} else {
run.setText(text);
}
} else if (value instanceof Number) {
run.setText(String.valueOf(value));
} else if (value instanceof Boolean) {
run.setText(value.toString());
} else if ((value instanceof Image) || (value instanceof ChartData)) {
Image img = null;
if (value instanceof Image) {
img = (Image) value;
} else {
ChartData chartData = (ChartData) value;
String base64Data = chartData.retriveBase64Data();
if (base64Data != null) {
img = new Image(base64Data, chartData.getWidth(), chartData.getHeight());
} else {
img = new Image("", chartData.getWidth(), chartData.getHeight());
}
}
String path = img.getPath();
String imageType = "png";
if (StringUtils.isNotBlank(path)) {
path = path.toLowerCase();
if (path.endsWith(".jpg") || path.endsWith(".jpeg")) {
imageType = "jpeg";
} else if (path.endsWith(".gif")) {
imageType = "gif";
}
}
String base64Data = img.getBase64Data();
if (StringUtils.isNotBlank(base64Data)) {
InputStream inputStream = null;
try {
inputStream = ImageUtils.base64DataToInputStream(base64Data);
BufferedImage bufferedImage = ImageIO.read(inputStream);
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
IOUtils.closeQuietly(inputStream);
inputStream = ImageUtils.base64DataToInputStream(base64Data);
width = UnitUtils.pixelToPoint(width);
height = UnitUtils.pixelToPoint(height);
if (imageType.equals("jpeg")) {
run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_JPEG, "ureport-" + rowNumber + "-" + columnNumber + ".jpg", Units.toEMU(width), Units.toEMU(height));
} else if (imageType.equals("png")) {
run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, "ureport-" + rowNumber + "-" + columnNumber + ".png", Units.toEMU(width), Units.toEMU(height));
} else if (imageType.equals("gif")) {
run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_GIF, "ureport-" + rowNumber + "-" + columnNumber + ".gif", Units.toEMU(width), Units.toEMU(height));
}
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
} else if (value instanceof Date) {
Date date = (Date) value;
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
run.setText(sd.format(date));
}
String fontFamily = style.getFontFamily();
if (customStyle != null && StringUtils.isNotBlank(customStyle.getFontFamily())) {
fontFamily = customStyle.getFontFamily();
}
if (rowStyle != null && StringUtils.isNotBlank(rowStyle.getFontFamily())) {
fontFamily = rowStyle.getFontFamily();
}
if (colStyle != null && StringUtils.isNotBlank(colStyle.getFontFamily())) {
fontFamily = colStyle.getFontFamily();
}
if (StringUtils.isNotBlank(fontFamily)) {
run.setFontFamily(fontFamily);
}
int fontSize = style.getFontSize();
if (customStyle != null && customStyle.getFontSize() > 0) {
fontSize = customStyle.getFontSize();
}
if (rowStyle != null && rowStyle.getFontSize() > 0) {
fontSize = rowStyle.getFontSize();
}
if (colStyle != null && colStyle.getFontSize() > 0) {
fontSize = colStyle.getFontSize();
}
if (fontSize > 0) {
run.setFontSize(fontSize);
}
boolean bold = style.getBold() == null ? false : style.getBold();
if (customStyle != null && customStyle.getBold() != null) {
bold = customStyle.getBold();
}
if (rowStyle != null && rowStyle.getBold() != null) {
bold = rowStyle.getBold();
}
if (colStyle != null && colStyle.getBold() != null) {
bold = colStyle.getBold();
}
if (bold) {
run.setBold(true);
}
boolean italic = style.getItalic() == null ? false : style.getItalic();
if (customStyle != null && customStyle.getItalic() != null) {
italic = customStyle.getItalic();
}
if (rowStyle != null && rowStyle.getItalic() != null) {
italic = rowStyle.getItalic();
}
if (colStyle != null && colStyle.getItalic() != null) {
italic = colStyle.getItalic();
}
if (italic) {
run.setItalic(true);
}
boolean underline = style.getUnderline() == null ? false : style.getUnderline();
if (customStyle != null && customStyle.getUnderline() != null) {
underline = customStyle.getUnderline();
}
if (rowStyle != null && rowStyle.getUnderline() != null) {
underline = rowStyle.getUnderline();
}
if (colStyle != null && colStyle.getUnderline() != null) {
underline = colStyle.getUnderline();
}
if (underline) {
run.setUnderline(UnderlinePatterns.SINGLE);
}
String bgcolor = style.getBgcolor();
if (customStyle != null && StringUtils.isNotBlank(customStyle.getBgcolor())) {
bgcolor = customStyle.getBgcolor();
}
if (rowStyle != null && StringUtils.isNotBlank(rowStyle.getBgcolor())) {
bgcolor = rowStyle.getBgcolor();
}
if (colStyle != null && StringUtils.isNotBlank(colStyle.getBgcolor())) {
bgcolor = colStyle.getBgcolor();
}
if (bgcolor != null) {
CTShd ctshd = cellProperties.addNewShd();
ctshd.setFill(toHex(bgcolor.split(",")));
}
String forecolor = style.getForecolor();
if (customStyle != null && StringUtils.isNotBlank(customStyle.getForecolor())) {
forecolor = customStyle.getForecolor();
}
if (rowStyle != null && StringUtils.isNotBlank(rowStyle.getForecolor())) {
forecolor = rowStyle.getForecolor();
}
if (colStyle != null && StringUtils.isNotBlank(colStyle.getForecolor())) {
forecolor = colStyle.getForecolor();
}
if (forecolor != null) {
run.setColor(toHex(forecolor.split(",")));
}
Alignment align = style.getAlign();
if (customStyle != null && customStyle.getAlign() != null) {
align = customStyle.getAlign();
}
if (rowStyle != null && rowStyle.getAlign() != null) {
align = rowStyle.getAlign();
}
if (align != null) {
if (align.equals(Alignment.left)) {
para.setAlignment(ParagraphAlignment.LEFT);
} else if (align.equals(Alignment.right)) {
para.setAlignment(ParagraphAlignment.RIGHT);
} else if (align.equals(Alignment.center)) {
para.setAlignment(ParagraphAlignment.CENTER);
}
}
if (style.getLineHeight() > 0) {
para.setSpacingBetween(style.getLineHeight());
}
align = style.getValign();
if (customStyle != null && customStyle.getValign() != null) {
align = customStyle.getValign();
}
if (rowStyle != null && rowStyle.getValign() != null) {
align = rowStyle.getValign();
}
if (colStyle != null && colStyle.getValign() != null) {
align = colStyle.getValign();
}
if (align != null) {
CTVerticalJc verticalAlign = cellProperties.addNewVAlign();
if (align.equals(Alignment.top)) {
verticalAlign.setVal(STVerticalJc.TOP);
} else if (align.equals(Alignment.middle)) {
verticalAlign.setVal(STVerticalJc.CENTER);
} else if (align.equals(Alignment.bottom)) {
verticalAlign.setVal(STVerticalJc.BOTTOM);
}
}
int startCol = columnNumber;
int startRow = rowNumber;
int endRow = startRow, endCol = startCol;
if (colSpan > 0) {
endCol = startCol + colSpan - 1;
}
if (rowSpan > 0) {
endRow = startRow + rowSpan - 1;
}
if (startCol != endCol) {
if (rowSpan > 0) {
for (int i = startRow; i <= endRow; i++) {
mergeCellsHorizontal(table, i, startCol, endCol);
}
} else {
mergeCellsHorizontal(table, startRow, startCol, endCol);
}
}
if (startRow != endRow) {
if (colSpan > 0) {
for (int i = startCol; i <= endCol; i++) {
mergeCellsVertically(table, i, startRow, endRow);
}
} else {
mergeCellsVertically(table, startCol, startRow, endRow);
}
}
}
private void mergeCellsHorizontal(XWPFTable table, int row, int startCol, int endCol) {
for (int cellIndex = startCol; cellIndex <= endCol; cellIndex++) {
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
if (cellIndex == startCol) {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
private void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
if (rowIndex == fromRow) {
cell.getCTTc().addNewTcPr().addNewVMerge()
.setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}
}
private void buildCellBorder(Border border, XWPFTableCell tableCell, int type) {
CTTcPr cellPropertie = tableCell.getCTTc().getTcPr();
if (cellPropertie == null) {
cellPropertie = tableCell.getCTTc().addNewTcPr();
}
CTTcBorders borders = cellPropertie.getTcBorders();
if (borders == null) {
borders = cellPropertie.addNewTcBorders();
;
}
BorderStyle borderStyle = border.getStyle();
CTBorder ctborder = null;
if (type == 1) {
ctborder = borders.addNewLeft();
} else if (type == 2) {
ctborder = borders.addNewRight();
} else if (type == 3) {
ctborder = borders.addNewTop();
} else if (type == 4) {
ctborder = borders.addNewBottom();
}
if (borderStyle.equals(BorderStyle.dashed)) {
ctborder.setVal(STBorder.DASHED);
} else if (borderStyle.equals(BorderStyle.doublesolid)) {
ctborder.setVal(STBorder.DOUBLE);
} else {
ctborder.setVal(STBorder.SINGLE);
}
int borderWidth = border.getWidth();
if (borderWidth > 1) {
ctborder.setSz(BigInteger.valueOf(DxaUtils.points2dxa(borderWidth)));
}
String color = border.getColor();
if (StringUtils.isNotBlank(color)) {
ctborder.setColor(toHex(color.split(",")));
}
}
private String toHex(String rgb[]) {
StringBuffer sb = new StringBuffer();
String R = Integer.toHexString(Integer.valueOf(rgb[0]));
String G = Integer.toHexString(Integer.valueOf(rgb[1]));
String B = Integer.toHexString(Integer.valueOf(rgb[2]));
R = R.length() == 1 ? "0" + R : R;
G = G.length() == 1 ? "0" + G : G;
B = B.length() == 1 ? "0" + B : B;
sb.append(R);
sb.append(G);
sb.append(B);
return sb.toString();
}
}
@@ -0,0 +1,223 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.parser;
import com.bstek.ureport.cache.ResourceCache;
import com.bstek.ureport.definition.*;
import com.bstek.ureport.definition.value.Slash;
import com.bstek.ureport.definition.value.SlashValue;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.utils.UnitUtils;
import org.springblade.core.tool.utils.Base64Util;
import javax.imageio.ImageIO;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
/**
* @author Jacky.gao
* @since 2017年3月17日
*/
public class SlashBuilder {
public void buildSlashImage(CellDefinition cell, ReportDefinition report) {
int rowNumber = cell.getRowNumber();
int colNumber = cell.getColumnNumber();
int rowSpan = cell.getRowSpan();
int colSpan = cell.getColSpan();
int verticalBorderWidth = 0, horizontalBorderWidth = 0;
CellStyle cellStyle = cell.getCellStyle();
if (cellStyle.getLeftBorder() != null) {
verticalBorderWidth += cellStyle.getLeftBorder().getWidth();
}
if (cellStyle.getRightBorder() != null) {
verticalBorderWidth += cellStyle.getRightBorder().getWidth();
}
if (cellStyle.getTopBorder() != null) {
horizontalBorderWidth = cellStyle.getTopBorder().getWidth();
}
if (cellStyle.getBottomBorder() != null) {
horizontalBorderWidth = cellStyle.getBottomBorder().getWidth();
}
int width = 0;
int height = 0;
if (rowSpan == 0) {
rowSpan = 1;
}
if (colSpan == 0) {
colSpan = 1;
}
List<ColumnDefinition> columns = report.getColumns();
List<RowDefinition> rows = report.getRows();
for (int i = colNumber; i < (colNumber + colSpan); i++) {
ColumnDefinition col = columns.get(i - 1);
width += UnitUtils.pointToPixel(col.getWidth());
}
for (int i = rowNumber; i < (rowNumber + rowSpan); i++) {
RowDefinition row = rows.get(i - 1);
height += UnitUtils.pointToPixel(row.getHeight());
}
width -= horizontalBorderWidth;
height -= verticalBorderWidth;
SlashValue content = (SlashValue) cell.getValue();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics2D g = (Graphics2D) image.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
Font font = cellStyle.getFont();
g.setFont(font);
g.setStroke(new BasicStroke(1f));
String bgColor = cellStyle.getBgcolor();
if (bgColor == null) {
bgColor = "255,255,255";
}
g.setColor(getColor(bgColor));
g.fillRect(0, 0, width, height);
AffineTransform transform = g.getTransform();
int allRowHeight = 0;
int index = 0;
String lc = cellStyle.getForecolor();
if (lc == null) {
lc = "0,0,0";
}
Color lineColor = getColor(lc);
String fc = cellStyle.getForecolor();
if (fc == null) {
fc = "0,0,0";
}
Color fontColor = getColor(fc);
for (int i = rowNumber; i < (rowNumber + rowSpan); i++) {
Slash slash = getSlash(content, index);
if (slash == null) {
break;
}
String text = slash.getText();
if (text == null) {
break;
}
RowDefinition row = rows.get(i - 1);
int rowHeight = UnitUtils.pointToPixel(row.getHeight());
g.setColor(fontColor);
int x = slash.getX();
int y = slash.getY();
g.rotate(Math.toRadians(slash.getDegree()), x, y);
g.drawString(text, x, y);
g.setTransform(transform);
g.setColor(lineColor);
int h = allRowHeight + rowHeight;
if (i == (rowNumber + rowSpan - 1)) {
h = allRowHeight + (rowHeight / 3) * 2;
}
g.drawLine(0, 0, width, h);
allRowHeight += rowHeight;
index++;
}
Slash slash = getSlash(content, index);
if (slash != null) {
String text = slash.getText();
if (text != null) {
int x = slash.getX();
int y = slash.getY();
g.rotate(Math.toRadians(slash.getDegree()), x, y);
g.setColor(fontColor);
g.drawString(text, x, y);
g.setTransform(transform);
index++;
}
}
if (colSpan > 0) {
colSpan--;
}
int colNumberStart = colNumber + colSpan;
for (int i = colNumberStart; i > (colNumber - 1); i--) {
slash = getSlash(content, index);
if (slash == null) {
break;
}
String text = slash.getText();
if (text == null) {
break;
}
int x = slash.getX();
int y = slash.getY();
g.rotate(Math.toRadians(slash.getDegree()), x, y);
g.setColor(fontColor);
g.drawString(text, x, y);
g.setTransform(transform);
ColumnDefinition col = columns.get(i - 1);
int colWidth = UnitUtils.pointToPixel(col.getWidth());
int w = width;
if (i == colNumberStart) {
w = width - colWidth / 3;
}
g.setColor(lineColor);
g.drawLine(0, 0, w, height);
width -= colWidth;
index++;
}
byte[] imageBytes = null;
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
MemoryCacheImageOutputStream memoryImage = new MemoryCacheImageOutputStream(byteOutput);
try {
ImageIO.write(image, "png", memoryImage);
imageBytes = byteOutput.toByteArray();
String base64Data = Base64Util.encodeToString(imageBytes);
content.setBase64Data(base64Data);
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
try {
if (memoryImage != null) {
memoryImage.close();
}
if (byteOutput != null) {
byteOutput.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
g.dispose();
String imageByteKey = buildKey(report.getReportFullName(), cell.getName());
ResourceCache.putObject(imageByteKey, imageBytes);
}
private Slash getSlash(SlashValue content, int index) {
List<Slash> slashes = content.getSlashes();
if (index < slashes.size()) {
return slashes.get(index);
}
return null;
}
private Color getColor(String text) {
if (text == null) {
return null;
}
String[] str = text.split(",");
return new Color(Integer.valueOf(str[0]), Integer.valueOf(str[1]), Integer.valueOf(str[2]));
}
public static String buildKey(String reportFullName, String cellName) {
return "slash-" + reportFullName + "-" + cellName;
}
}
@@ -0,0 +1,71 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.provider.image;
import com.bstek.ureport.exception.ReportComputeException;
import jakarta.servlet.ServletContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ResourceUtils;
import org.springframework.web.context.ServletContextAware;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Jacky.gao
* @since 2017年3月6日
*/
public class DefaultImageProvider implements ImageProvider, ApplicationContextAware, ServletContextAware {
private ApplicationContext applicationContext;
private String baseWebPath;
@Override
public InputStream getImage(String path) {
try {
if (path.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) || path.startsWith("/WEB-INF")) {
return applicationContext.getResource(path).getInputStream();
} else {
path = baseWebPath + path;
return new FileInputStream(path);
}
} catch (IOException e) {
throw new ReportComputeException(e);
}
}
@Override
public boolean support(String path) {
if (path.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
return true;
} else if (baseWebPath != null && (path.startsWith("/") || path.startsWith("/WEB-INF"))) {
return true;
}
return false;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.baseWebPath = servletContext.getRealPath("/");
}
}
@@ -0,0 +1,147 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.provider.report.file;
import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.ReportProvider;
import jakarta.servlet.ServletContext;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import java.io.*;
import java.util.*;
/**
* @author Jacky.gao
* @since 2017年2月11日
*/
public class FileReportProvider implements ReportProvider, ApplicationContextAware {
private String prefix = "file:";
private String fileStoreDir;
private boolean disabled;
@Override
public InputStream loadReport(String file) {
if (file.startsWith(prefix)) {
file = file.substring(prefix.length(), file.length());
}
String fullPath = fileStoreDir + "/" + file;
try {
return new FileInputStream(fullPath);
} catch (FileNotFoundException e) {
throw new ReportException(e);
}
}
@Override
public void deleteReport(String file) {
if (file.startsWith(prefix)) {
file = file.substring(prefix.length(), file.length());
}
String fullPath = fileStoreDir + "/" + file;
File f = new File(fullPath);
if (f.exists()) {
f.delete();
}
}
@Override
public List<ReportFile> getReportFiles() {
File file = new File(fileStoreDir);
List<ReportFile> list = new ArrayList<ReportFile>();
for (File f : file.listFiles()) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(f.lastModified());
list.add(new ReportFile(f.getName(), calendar.getTime()));
}
Collections.sort(list, new Comparator<ReportFile>() {
@Override
public int compare(ReportFile f1, ReportFile f2) {
return f2.getUpdateDate().compareTo(f1.getUpdateDate());
}
});
return list;
}
@Override
public String getName() {
return "服务器文件系统";
}
@Override
public void saveReport(String file, String content) {
if (file.startsWith(prefix)) {
file = file.substring(prefix.length(), file.length());
}
String fullPath = fileStoreDir + "/" + file;
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(new File(fullPath));
IOUtils.write(content, outStream, "utf-8");
} catch (Exception ex) {
throw new ReportException(ex);
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public boolean disabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
public void setFileStoreDir(String fileStoreDir) {
this.fileStoreDir = fileStoreDir;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
File file = new File(fileStoreDir);
if (file.exists()) {
return;
}
if (applicationContext instanceof WebApplicationContext) {
WebApplicationContext context = (WebApplicationContext) applicationContext;
ServletContext servletContext = context.getServletContext();
String basePath = servletContext.getRealPath("/");
fileStoreDir = basePath + fileStoreDir;
file = new File(fileStoreDir);
if (!file.exists()) {
file.mkdirs();
}
}
}
@Override
public String getPrefix() {
return prefix;
}
}
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.utils;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.image.ChartImageProcessor;
import com.bstek.ureport.image.ImageProcessor;
import com.bstek.ureport.image.ImageType;
import com.bstek.ureport.image.StaticImageProcessor;
import org.apache.commons.io.IOUtils;
import org.springblade.core.tool.utils.Base64Util;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年3月20日
*/
public class ImageUtils {
private static Map<ImageType, ImageProcessor<?>> imageProcessorMap = new HashMap<ImageType, ImageProcessor<?>>();
static {
StaticImageProcessor staticImageProcessor = new StaticImageProcessor();
imageProcessorMap.put(ImageType.image, staticImageProcessor);
ChartImageProcessor chartImageProcessor = new ChartImageProcessor();
imageProcessorMap.put(ImageType.chart, chartImageProcessor);
}
public static InputStream base64DataToInputStream(String base64Data) {
byte[] bytes = Base64Util.decodeFromString(base64Data);
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
return inputStream;
}
@SuppressWarnings("unchecked")
public static String getImageBase64Data(ImageType type, Object data, int width, int height) {
ImageProcessor<Object> targetProcessor = (ImageProcessor<Object>) imageProcessorMap.get(type);
if (targetProcessor == null) {
throw new ReportComputeException("Unknow image type :" + type);
}
InputStream inputStream = targetProcessor.getImage(data);
try {
if (width > 0 && height > 0) {
BufferedImage inputImage = ImageIO.read(inputStream);
BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_565_RGB);
Graphics2D g = outputImage.createGraphics();
g.drawImage(inputImage, 0, 0, width, height, null);
g.dispose();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(outputImage, "png", outputStream);
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
}
byte[] bytes = IOUtils.toByteArray(inputStream);
return Base64Util.encodeToString(bytes);
} catch (Exception ex) {
throw new ReportComputeException(ex);
} finally {
IOUtils.closeQuietly(inputStream);
}
}
}
@@ -0,0 +1,56 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.config;
import jakarta.servlet.Filter;
import org.springblade.core.report.filter.UReportAuthFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
/**
* UReport认证配置类
*
* @author BladeX
*/
@Order
@AutoConfiguration
@ConditionalOnProperty(value = "report.auth", havingValue = "true", matchIfMissing = true)
public class ReportAuthConfiguration {
@Bean
public FilterRegistrationBean<Filter> uReportAuthFilter() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new UReportAuthFilter());
registration.addUrlPatterns("/ureport/*");
registration.setName("uReportAuthFilter");
registration.setOrder(1);
return registration;
}
}
@@ -0,0 +1,74 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.config;
import com.bstek.ureport.UReportPropertyPlaceholderConfigurer;
import com.bstek.ureport.console.UReportServlet;
import com.bstek.ureport.provider.report.ReportProvider;
import jakarta.servlet.Servlet;
import org.springblade.core.report.props.ReportDatabaseProperties;
import org.springblade.core.report.props.ReportProperties;
import org.springblade.core.report.provider.DatabaseProvider;
import org.springblade.core.report.provider.ReportPlaceholderProvider;
import org.springblade.core.report.service.IReportFileService;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.annotation.Order;
/**
* UReport配置类
*
* @author Chill
*/
@Order
@AutoConfiguration
@ConditionalOnProperty(value = "report.enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties({ReportProperties.class, ReportDatabaseProperties.class})
@ImportResource("classpath:ureport-console-context.xml")
public class ReportConfiguration {
@Bean
public ServletRegistrationBean<Servlet> registrationBean() {
return new ServletRegistrationBean<>(new UReportServlet(), "/ureport/*");
}
@Bean
public UReportPropertyPlaceholderConfigurer uReportPropertyPlaceholderConfigurer(ReportProperties properties) {
return new ReportPlaceholderProvider(properties);
}
@Bean
@ConditionalOnMissingBean
public ReportProvider reportProvider(ReportDatabaseProperties properties, IReportFileService service) {
return new DatabaseProvider(properties, service);
}
}
@@ -0,0 +1,64 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.datasource;
import com.bstek.ureport.definition.datasource.BuildinDatasource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* UReport数据源配置
*
* @author Chill
*/
@Slf4j
@AllArgsConstructor
public class ReportDataSource implements BuildinDatasource {
private static final String NAME = "ReportDataSource";
private final DataSource dataSource;
@Override
public String name() {
return NAME;
}
@Override
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
log.error("report数据源链接失败");
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,48 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.endpoint;
import io.swagger.v3.oas.annotations.Hidden;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.report.service.IReportFileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* UReport Boot版 API端点
*
* @author Chill
*/
@Hidden
@RestController
@RequestMapping(AppConstant.APPLICATION_REPORT_NAME + "/report/rest")
public class ReportBootEndpoint extends ReportEndpoint {
public ReportBootEndpoint(IReportFileService service) {
super(service);
}
}
@@ -0,0 +1,81 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.endpoint;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.report.entity.ReportFileEntity;
import org.springblade.core.report.service.IReportFileService;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* UReport API端点
*
* @author Chill
*/
@Hidden
@RestController
@AllArgsConstructor
@RequestMapping("/report/rest")
public class ReportEndpoint {
private final IReportFileService service;
/**
* 详情
*/
@GetMapping("/detail")
public R<ReportFileEntity> detail(ReportFileEntity file) {
ReportFileEntity detail = service.getOne(Condition.getQueryWrapper(file));
return R.data(detail);
}
/**
* 分页
*/
@GetMapping("/list")
public R<IPage<ReportFileEntity>> list(@RequestParam Map<String, Object> file, Query query) {
IPage<ReportFileEntity> pages = service.page(Condition.getPage(query), Condition.getQueryWrapper(file, ReportFileEntity.class));
return R.data(pages);
}
/**
* 删除
*/
@PostMapping("/remove")
public R remove(@RequestParam String ids) {
boolean temp = service.removeByIds(Func.toLongList(ids));
return R.status(temp);
}
}
@@ -0,0 +1,80 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* UReport实体类
*
* @author Chill
*/
@Data
@TableName("blade_report_file")
public class ReportFileEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 文件名
*/
private String name;
/**
* 文件内容
*/
private byte[] content;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否已删除
*/
@TableLogic
private Integer isDeleted;
}
@@ -0,0 +1,213 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.filter;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.WebUtil;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
/**
* UReport 鉴权过滤器
*
* <p>处理 /ureport/* 路径的访问鉴权,放行前端资源文件</p>
*
* @author BladeX
*/
@Slf4j
public class UReportAuthFilter implements Filter {
/**
* 前端资源文件扩展名
*/
private static final List<String> STATIC_RESOURCE_EXTENSIONS = Arrays.asList(
".js", ".css", ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg",
".woff", ".woff2", ".ttf", ".eot", ".map", ".html", ".htm"
);
/**
* 资源文件路径前缀
*/
private static final String RESOURCE_PATH_PREFIX = "/ureport/res/ureport-asserts";
/**
* Session 中存储认证状态的键名
*/
private static final String SESSION_AUTH_KEY = "UREPORT_AUTHENTICATED";
/**
* Session 中存储用户信息的键名
*/
private static final String SESSION_USER_KEY = "UREPORT_USER_INFO";
/**
* Session 中存储用户主键的键名
*/
private static final String SESSION_USER_ID = "UREPORT_USER_ID";
/**
* Session 超时时间,单位为秒
*/
private static final Integer INTERVAL_TIME = 120 * 60;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestURI = WebUtil.getRequestURI(httpRequest);
String requestIP = WebUtil.getIP(httpRequest);
// 检查是否为静态资源文件,如果是则直接放行
if (isStaticResource(requestURI)) {
chain.doFilter(request, response);
return;
}
// 验证用户是否已认证(优先检查 Session,再检查 Token
if (!isAuthenticatedWithSession(httpRequest)) {
log.warn("未授权访问 UReport API: {}, IP: {}", requestURI, requestIP);
handleUnauthorized(httpResponse);
return;
}
// 验证通过放行请求
chain.doFilter(request, response);
}
/**
* 判断是否为静态资源文件
*/
private boolean isStaticResource(String requestURI) {
// 检查是否为资源文件路径
if (requestURI.startsWith(RESOURCE_PATH_PREFIX)) {
return true;
}
// 检查文件扩展名
String lowerCaseURI = requestURI.toLowerCase();
return STATIC_RESOURCE_EXTENSIONS.stream()
.anyMatch(lowerCaseURI::endsWith);
}
/**
* 验证用户是否已认证(Session + Token 双重验证)
*/
private boolean isAuthenticatedWithSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
// 1. 优先检查 Session 认证状态
if (session != null && Boolean.TRUE.equals(session.getAttribute(SESSION_AUTH_KEY))) {
log.debug("Session 认证有效,用户: {}", session.getAttribute(SESSION_USER_KEY));
return true;
}
// 2. Session 无效,尝试 Token 认证
if (isTokenAuthenticated(request)) {
// Token 认证成功,建立 Session
establishSession(request);
log.info("Token 认证成功,已建立 Session 会话");
return true;
}
return false;
}
/**
* Token 认证验证
*/
private boolean isTokenAuthenticated(HttpServletRequest request) {
try {
Long userId = AuthUtil.getUserId(request);
return userId != null && userId > 0;
} catch (Exception e) {
log.debug("Token 认证失败: {}", e.getMessage());
return false;
}
}
/**
* 建立认证会话
*/
private void establishSession(HttpServletRequest request) {
HttpSession session = request.getSession(true);
try {
String userAccount = AuthUtil.getUserAccount(request);
Long userId = AuthUtil.getUserId(request);
// 设置认证标记
session.setAttribute(SESSION_AUTH_KEY, true);
session.setAttribute(SESSION_USER_KEY, userAccount);
session.setAttribute(SESSION_USER_ID, userId);
// 设置 Session 超时时间(60分钟)
session.setMaxInactiveInterval(INTERVAL_TIME);
log.debug("建立 UReport 认证会话: 用户 {}, SessionID: {}", userAccount, session.getId());
} catch (Exception e) {
log.warn("建立认证会话失败: {}", e.getMessage());
}
}
/**
* 从 Session 获取用户账号
*/
private String getUserFromSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
Object userAccount = session.getAttribute(SESSION_USER_KEY);
return userAccount != null ? userAccount.toString() : "未知用户";
}
return "未知用户";
}
/**
* 处理未授权访问
*/
private void handleUnauthorized(HttpServletResponse response) throws IOException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
try (PrintWriter writer = response.getWriter()) {
writer.write("访问 UReport 需要 BladeX 的 Token 认证");
writer.flush();
}
}
}
@@ -0,0 +1,37 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.core.report.entity.ReportFileEntity;
/**
* UReport Mapper
*
* @author Chill
*/
public interface ReportFileMapper extends BaseMapper<ReportFileEntity> {
}
@@ -0,0 +1,42 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.props;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* UReport配置类
*
* @author Chill
*/
@Data
@ConfigurationProperties(prefix = "report.database.provider")
public class ReportDatabaseProperties {
private String name = "数据库文件系统";
private String prefix = "blade-";
private boolean disabled = false;
}
@@ -0,0 +1,46 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.props;
import lombok.Data;
import org.springblade.core.tool.utils.StringPool;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* UReport配置类
*
* @author Chill
*/
@Data
@ConfigurationProperties(prefix = "report")
public class ReportProperties {
private Boolean enabled = true;
private Boolean auth = true;
private Boolean disableHttpSessionReportCache = false;
private Boolean disableFileProvider = true;
private String fileStoreDir = StringPool.EMPTY;
private Boolean debug = false;
}
@@ -0,0 +1,120 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.provider;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.ReportProvider;
import lombok.AllArgsConstructor;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.report.entity.ReportFileEntity;
import org.springblade.core.report.props.ReportDatabaseProperties;
import org.springblade.core.report.service.IReportFileService;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 数据库文件处理
*
* @author Chill
*/
@AllArgsConstructor
public class DatabaseProvider implements ReportProvider {
private final ReportDatabaseProperties properties;
private final IReportFileService service;
@Override
public InputStream loadReport(String file) {
ReportFileEntity reportFileEntity = service.getOne(Wrappers.<ReportFileEntity>lambdaQuery().eq(ReportFileEntity::getName, getFileName(file)));
byte[] content = reportFileEntity.getContent();
return new ByteArrayInputStream(content);
}
@Override
public void deleteReport(String file) {
service.remove(Wrappers.<ReportFileEntity>lambdaUpdate().eq(ReportFileEntity::getName, getFileName(file)));
}
@Override
public List<ReportFile> getReportFiles() {
List<ReportFileEntity> list = service.list();
List<ReportFile> reportFiles = new ArrayList<>();
list.forEach(reportFileEntity -> reportFiles.add(new ReportFile(reportFileEntity.getName(), reportFileEntity.getUpdateTime())));
return reportFiles;
}
@Override
public void saveReport(String file, String content) {
String fileName = getFileName(file);
ReportFileEntity reportFileEntity = service.getOne(Wrappers.<ReportFileEntity>lambdaQuery().eq(ReportFileEntity::getName, fileName));
Date now = DateUtil.now();
if (reportFileEntity == null) {
reportFileEntity = new ReportFileEntity();
reportFileEntity.setName(fileName);
reportFileEntity.setContent(content.getBytes());
reportFileEntity.setCreateTime(now);
reportFileEntity.setIsDeleted(BladeConstant.DB_NOT_DELETED);
} else {
reportFileEntity.setContent(content.getBytes());
}
reportFileEntity.setUpdateTime(now);
service.saveOrUpdate(reportFileEntity);
}
@Override
public String getName() {
return properties.getName();
}
@Override
public boolean disabled() {
return properties.isDisabled();
}
@Override
public String getPrefix() {
return properties.getPrefix();
}
/**
* 获取标准格式文件名
*
* @param name 原文件名
*/
private String getFileName(String name) {
if (name.startsWith(getPrefix())) {
name = name.substring(getPrefix().length());
}
return name;
}
}
@@ -0,0 +1,49 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.provider;
import com.bstek.ureport.UReportPropertyPlaceholderConfigurer;
import org.springblade.core.report.props.ReportProperties;
import java.util.Properties;
/**
* UReport自定义配置
*
* @author Chill
*/
public class ReportPlaceholderProvider extends UReportPropertyPlaceholderConfigurer {
public ReportPlaceholderProvider(ReportProperties properties) {
Properties props = new Properties();
props.setProperty("ureport.disableHttpSessionReportCache", properties.getDisableHttpSessionReportCache().toString());
props.setProperty("ureport.disableFileProvider", properties.getDisableFileProvider().toString());
props.setProperty("ureport.fileStoreDir", properties.getFileStoreDir());
props.setProperty("ureport.debug", properties.getDebug().toString());
this.setProperties(props);
}
}
@@ -0,0 +1,37 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springblade.core.report.entity.ReportFileEntity;
/**
* UReport Service
*
* @author Chill
*/
public interface IReportFileService extends IService<ReportFileEntity> {
}
@@ -0,0 +1,41 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.core.report.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.core.report.entity.ReportFileEntity;
import org.springblade.core.report.mapper.ReportFileMapper;
import org.springblade.core.report.service.IReportFileService;
import org.springframework.stereotype.Service;
/**
* UReport Service
*
* @author Chill
*/
@Service
public class ReportFileServiceImpl extends ServiceImpl<ReportFileMapper, ReportFileEntity> implements IReportFileService {
}