This commit is contained in:
2025-11-28 16:23:32 +08:00
commit a9e0e16c29
826 changed files with 89805 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>BladeX-Tool</artifactId>
<groupId>org.springblade</groupId>
<version>${revision}</version>
</parent>
<artifactId>blade-starter-report</artifactId>
<name>${project.artifactId}</name>
<version>${project.parent.version}</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-console</artifactId>
<exclusions>
<exclusion>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
<version>2.2.9</version>
</dependency>
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-core</artifactId>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
<version>2.2.9</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<!-- Auto -->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-auto</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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;
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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;
}
}

View File

@@ -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";
}
}

View File

@@ -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;
}
}

View File

@@ -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.List;
import java.util.*;
/**
* @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, Integer.parseInt(String.valueOf(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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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("/");
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,75 @@
/**
* 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 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;
import jakarta.servlet.Servlet;
/**
* 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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,77 @@
/**
* 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 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)
private Long id;
/**
* 文件名
*/
private String name;
/**
* 文件内容
*/
private byte[] content;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否已删除
*/
@TableLogic
private Integer isDeleted;
}

View File

@@ -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> {
}

View File

@@ -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;
}

View File

@@ -0,0 +1,45 @@
/**
* 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 disableHttpSessionReportCache = false;
private Boolean disableFileProvider = true;
private String fileStoreDir = StringPool.EMPTY;
private Boolean debug = false;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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> {
}

View File

@@ -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 {
}