pioneer
2 years ago
commit
700d927237
15 changed files with 2849 additions and 0 deletions
@ -0,0 +1,6 @@
|
||||
# open-JSD-9772 |
||||
|
||||
JSD-9772 目前文件导出之后sheet名称为模板名称加上后缀,想要导出后每个sheet都和原本模板中设置的sheet名保持一致\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,86 @@
|
||||
{ |
||||
"id": "825cd73d-8730-c322-5d6b-5ea35a9f8211", |
||||
"name": "JSD9772", |
||||
"description": "", |
||||
"order": [ |
||||
"41142dfc-7964-8674-5b9f-4fb0975b5fac", |
||||
"20c4f67c-3cf9-cd19-0b84-f8c4ec9f36c3" |
||||
], |
||||
"folders": [], |
||||
"folders_order": [], |
||||
"timestamp": 1652413133763, |
||||
"owner": 0, |
||||
"public": false, |
||||
"requests": [ |
||||
{ |
||||
"id": "20c4f67c-3cf9-cd19-0b84-f8c4ec9f36c3", |
||||
"headers": "Content-Type: application/json\nAuthorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiZGVmYXVsdCIsImlzcyI6ImZhbnJ1YW4iLCJkZXNjcmlwdGlvbiI6ImFkbWluKGFkbWluKSIsImV4cCI6MTY1NDA0NjQ5MCwiaWF0IjoxNjUyODM2ODkwLCJqdGkiOiI2OU45MEpvOWVlL043cmQ1V2w5SVlrNEtOcjJDS3FyRlM5ai9BdVYxRmdRdVY3ZG0ifQ.1afJKlXYH80IE_OXfW0q3PxaZbmw0sCMB-jgsr9N6Gk\n", |
||||
"headerData": [ |
||||
{ |
||||
"key": "Content-Type", |
||||
"value": "application/json", |
||||
"description": "", |
||||
"enabled": true |
||||
}, |
||||
{ |
||||
"key": "Authorization", |
||||
"value": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiZGVmYXVsdCIsImlzcyI6ImZhbnJ1YW4iLCJkZXNjcmlwdGlvbiI6ImFkbWluKGFkbWluKSIsImV4cCI6MTY1NDA0NjQ5MCwiaWF0IjoxNjUyODM2ODkwLCJqdGkiOiI2OU45MEpvOWVlL043cmQ1V2w5SVlrNEtOcjJDS3FyRlM5ai9BdVYxRmdRdVY3ZG0ifQ.1afJKlXYH80IE_OXfW0q3PxaZbmw0sCMB-jgsr9N6Gk", |
||||
"description": "", |
||||
"enabled": true |
||||
} |
||||
], |
||||
"url": "http://localhost:8075/webroot/decision/url/api/export", |
||||
"queryParams": [], |
||||
"preRequestScript": null, |
||||
"pathVariables": {}, |
||||
"pathVariableData": [], |
||||
"method": "POST", |
||||
"data": [], |
||||
"dataMode": "raw", |
||||
"tests": null, |
||||
"currentHelper": "normal", |
||||
"helperAttributes": {}, |
||||
"time": 1652836913398, |
||||
"name": "/api/export-2", |
||||
"description": "", |
||||
"collectionId": "825cd73d-8730-c322-5d6b-5ea35a9f8211", |
||||
"responses": [], |
||||
"rawModeData": "{\r\n\t\"excel_name\": \"测试\",\r\n\t\"excel_type\": \"xlsx\",\r\n\t\"reports\": [{\r\n\t\t\"report_path\": \"jsd9772/MultiSheet.cpt\",\r\n\t\t\"parameters\": [{\r\n\t\t\t\"name\": \"产品类型\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"饮料\"\r\n\t\t}, {\r\n\t\t\t\"name\": \"地区\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"华东\"\r\n\t\t}],\r\n\t\t\"sheetParameters\": [{\r\n\t\t\t\"sheetIndex\": \"0\",\r\n\t\t\t\"sheetName\": \"订单\"\r\n\t\t}]\r\n\t}, {\r\n\t\t\"report_path\": \"jsd9772/MultiSheet2.cpt\",\r\n\t\t\"parameters\": [{\r\n\t\t\t\"name\": \"产品类型\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"饮料\"\r\n\t\t}, {\r\n\t\t\t\"name\": \"地区\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"华东\"\r\n\t\t}],\r\n\t\t\"sheetParameters\": [{\r\n\t\t\t\"sheetIndex\": \"1\",\r\n\t\t\t\"sheetName\": \"订单明细2\"\r\n\t\t}]\r\n\t}]\r\n}" |
||||
}, |
||||
{ |
||||
"id": "41142dfc-7964-8674-5b9f-4fb0975b5fac", |
||||
"headers": "Content-Type: application/json\nAuthorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiZGVmYXVsdCIsImlzcyI6ImZhbnJ1YW4iLCJkZXNjcmlwdGlvbiI6ImFkbWluKGFkbWluKSIsImV4cCI6MTY1MzYyMzExMCwiaWF0IjoxNjUyNDEzNTEwLCJqdGkiOiJwRjZQb3dxUWpJd3FQejRsUzZITVVxUXAzNnVVdEthV2dwTld3ZFhLSHRqc3ZIQlQifQ.XWOs-6vHNggGpySCXsJEVx5b5CUlBpzjSlnDPSLFTIM\n", |
||||
"headerData": [ |
||||
{ |
||||
"key": "Content-Type", |
||||
"value": "application/json", |
||||
"description": "", |
||||
"enabled": true |
||||
}, |
||||
{ |
||||
"key": "Authorization", |
||||
"value": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiZGVmYXVsdCIsImlzcyI6ImZhbnJ1YW4iLCJkZXNjcmlwdGlvbiI6ImFkbWluKGFkbWluKSIsImV4cCI6MTY1MzYyMzExMCwiaWF0IjoxNjUyNDEzNTEwLCJqdGkiOiJwRjZQb3dxUWpJd3FQejRsUzZITVVxUXAzNnVVdEthV2dwTld3ZFhLSHRqc3ZIQlQifQ.XWOs-6vHNggGpySCXsJEVx5b5CUlBpzjSlnDPSLFTIM", |
||||
"description": "", |
||||
"enabled": true |
||||
} |
||||
], |
||||
"url": "http://localhost:8075/webroot/decision/url/api/export", |
||||
"queryParams": [], |
||||
"preRequestScript": null, |
||||
"pathVariables": {}, |
||||
"pathVariableData": [], |
||||
"method": "POST", |
||||
"data": [], |
||||
"dataMode": "raw", |
||||
"tests": null, |
||||
"currentHelper": "normal", |
||||
"helperAttributes": {}, |
||||
"time": 1652802543697, |
||||
"name": "/api/export", |
||||
"description": "", |
||||
"collectionId": "825cd73d-8730-c322-5d6b-5ea35a9f8211", |
||||
"responses": [], |
||||
"rawModeData": "{\r\n\t\"excel_name\": \"测试\",\r\n\t\"excel_type\": \"xlsx\",\r\n\t\"reports\": [{\r\n\t\t\"report_path\": \"jsd9772/MultiSheet.cpt\",\r\n\t\t\"parameters\": [{\r\n\t\t\t\"name\": \"产品类型\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"饮料\"\r\n\t\t}, {\r\n\t\t\t\"name\": \"地区\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"华东\"\r\n\t\t}],\r\n\t\t\"sheetParameters\": [{\r\n\t\t\t\"sheetIndex\": \"0\",\r\n\t\t\t\"sheetName\": \"订单\"\r\n\t\t}, {\r\n\t\t\t\"sheetIndex\": \"1\",\r\n\t\t\t\"sheetName\": \"订单明细\"\r\n\t\t}]\r\n\t}, {\r\n\t\t\"report_path\": \"jsd9772/MultiSheet2.cpt\",\r\n\t\t\"parameters\": [{\r\n\t\t\t\"name\": \"产品类型\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"饮料\"\r\n\t\t}, {\r\n\t\t\t\"name\": \"地区\",\r\n\t\t\t\"type\": \"String\",\r\n\t\t\t\"value\": \"华东\"\r\n\t\t}],\r\n\t\t\"sheetParameters\": [{\r\n\t\t\t\"sheetIndex\": \"0\",\r\n\t\t\t\"sheetName\": \"订单2\"\r\n\t\t}, {\r\n\t\t\t\"sheetIndex\": \"1\",\r\n\t\t\t\"sheetName\": \"订单明细2\"\r\n\t\t}]\r\n\t}]\r\n}" |
||||
} |
||||
] |
||||
} |
Binary file not shown.
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<plugin> |
||||
<id>com.fr.plugin.igqb.sheet</id> |
||||
<name><![CDATA[导出Excel文件sheet定制]]></name> |
||||
<active>yes</active> |
||||
<version>1.0</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2018-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[导出Excel文件sheet定制]]></description> |
||||
<change-notes><![CDATA[ |
||||
<p>导出Excel文件sheet定制</p> |
||||
]]></change-notes> |
||||
<main-package>com.fr.plugin.igqb</main-package> |
||||
<prefer-packages> |
||||
<prefer-package>com.fanruan.api</prefer-package> |
||||
</prefer-packages> |
||||
<extra-core> |
||||
<LocaleFinder class="com.fr.plugin.igqb.LocaleFinder"/> |
||||
</extra-core> |
||||
<extra-decision> |
||||
<HttpHandlerProvider class="com.fr.plugin.igqb.service.RequestHandlerBridge"/> |
||||
<URLAliasProvider class="com.fr.plugin.igqb.service.URLAliasBridge"/> |
||||
</extra-decision> |
||||
<function-recorder class="com.fr.plugin.igqb.LocaleFinder"/> |
||||
</plugin> |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright (C), 2018-2020 |
||||
* Project: starter |
||||
* FileName: LocaleFinder |
||||
* Author: xx |
||||
* Date: 2020/8/31 22:19 |
||||
*/ |
||||
package com.fr.plugin.igqb; |
||||
|
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.fun.Authorize; |
||||
import com.fr.stable.fun.impl.AbstractLocaleFinder; |
||||
|
||||
import static com.fr.plugin.igqb.LocaleFinder.PLUGIN_ID; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <LocaleFinder> |
||||
* |
||||
* @author xx |
||||
* @since 1.0.0 |
||||
*/ |
||||
@EnableMetrics |
||||
@Authorize(callSignKey = PLUGIN_ID) |
||||
public class LocaleFinder extends AbstractLocaleFinder { |
||||
public static final String PLUGIN_ID = "com.fr.plugin.igqb.sheet"; |
||||
|
||||
@Override |
||||
@Focus(id = PLUGIN_ID, text = "Plugin-igqb", source = Original.PLUGIN) |
||||
public String find() { |
||||
return "com/fr/plugin/igqb/locale/lang"; |
||||
} |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
} |
@ -0,0 +1,195 @@
|
||||
|
||||
package com.fr.plugin.igqb.service; |
||||
|
||||
import com.fanruan.api.i18n.I18nKit; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.base.Parameter; |
||||
import com.fr.data.NetworkHelper; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.io.TemplateWorkBookIO; |
||||
import com.fr.io.exporter.ExcelExporter; |
||||
import com.fr.json.JSONArray; |
||||
import com.fr.json.JSONException; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.main.impl.WorkBook; |
||||
import com.fr.main.workbook.ResultWorkBook; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.stable.WriteActor; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.web.core.utils.ExportUtils; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.BufferedReader; |
||||
import java.io.IOException; |
||||
import java.io.InputStreamReader; |
||||
import java.io.OutputStream; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import static com.fr.plugin.igqb.LocaleFinder.PLUGIN_ID; |
||||
|
||||
/** |
||||
* 〈Function Description〉<br> |
||||
* 〈ReportDataHandler〉 |
||||
* |
||||
* @author xx |
||||
* @since 1.0.0 |
||||
*/ |
||||
@EnableMetrics |
||||
public class ReportDataHandler extends BaseHttpHandler { |
||||
public static final String REPORT_PATH = "report_path"; |
||||
public static final String API_EXPORT = "/api/export"; |
||||
public static final String EXCEL_NAME = "excel_name"; |
||||
public static final String EXCEL_TYPE = "excel_type"; |
||||
public static final String REPORTS = "reports"; |
||||
public static final String PARAMETERS = "parameters"; |
||||
public static final String SHEET_INDEX = "sheetIndex"; |
||||
public static final String SHEET_PARAMETERS = "sheetParameters"; |
||||
public static final String SHEET_NAME = "sheetName"; |
||||
|
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return RequestMethod.POST; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return API_EXPORT; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
@Focus(id = PLUGIN_ID, text = "Plugin-igqb", source = Original.PLUGIN) |
||||
public void handle(HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
if (!PluginContexts.currentContext().isAvailable()) { |
||||
LogKit.error(I18nKit.getLocText("Plugin-igqb_Licence_Expired")); |
||||
printErrorJSON(response); |
||||
return; |
||||
} |
||||
JSONObject params = getParams(request); |
||||
LogKit.info("igqb-ReportDataHandler:handle-params:{}", params.encode()); |
||||
try { |
||||
String fileName = params.getString(EXCEL_NAME); |
||||
String excelType = params.getString(EXCEL_TYPE); |
||||
if (StringKit.equals(excelType, "xls")) { |
||||
ExportUtils.setExcelContent(response, fileName); |
||||
} else { |
||||
ExportUtils.setExcel2007Content(response, fileName); |
||||
} |
||||
JSONArray reportData = params.getJSONArray(REPORTS); |
||||
OutputStream outputStream = response.getOutputStream(); |
||||
ResultWorkBook resultWorkBook = this.generateResultWorkBook(reportData); |
||||
this.export2temp(outputStream, resultWorkBook, excelType); |
||||
outputStream.close(); |
||||
} catch (JSONException e) { |
||||
LogKit.error(e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
private void export2temp(OutputStream outputStream, ResultWorkBook resultWorkBook, String excelType) throws Exception { |
||||
ExcelExporter exporter = new ExcelExporter(); |
||||
exporter.setVersion(StringKit.equals(excelType, "xls")); |
||||
exporter.export(outputStream, resultWorkBook); |
||||
} |
||||
|
||||
/** |
||||
* 多个模板计算ResultWorkBook并合并 |
||||
* |
||||
* @param reportData |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
private ResultWorkBook generateResultWorkBook(JSONArray reportData) throws Exception { |
||||
JSONObject report; |
||||
String reportPath; |
||||
Map<String, Object> parameterMap; |
||||
ResultWorkBook resultWorkBook = null; |
||||
WorkBook workbook; |
||||
ResultWorkBook reportWorkBook; |
||||
JSONArray sheetParameters = JSONArray.create(); |
||||
for (Object obj : reportData) { |
||||
report = (JSONObject) obj; |
||||
reportPath = report.getString(REPORT_PATH); |
||||
parameterMap = getParameters(report.getJSONArray(PARAMETERS)); |
||||
if (report.has(SHEET_PARAMETERS)) { |
||||
sheetParameters = report.getJSONArray(SHEET_PARAMETERS); |
||||
} |
||||
workbook = (WorkBook) TemplateWorkBookIO.readTemplateWorkBook(reportPath); |
||||
reportWorkBook = workbook.execute(parameterMap, new WriteActor()); |
||||
if (resultWorkBook == null) { |
||||
resultWorkBook = (ResultWorkBook) reportWorkBook.clone(); |
||||
resultWorkBook.removeReports(); |
||||
} |
||||
mergeWorkBook(resultWorkBook, reportWorkBook, sheetParameters); |
||||
} |
||||
return resultWorkBook; |
||||
} |
||||
|
||||
private void mergeWorkBook(ResultWorkBook resultWorkBook, ResultWorkBook reportWorkBook, JSONArray sheetParameters) { |
||||
String sheetName; |
||||
int sheetIndex; |
||||
for (Object obj : sheetParameters) { |
||||
JSONObject sheetParameter = (JSONObject) obj; |
||||
sheetIndex = sheetParameter.getInt(SHEET_INDEX); |
||||
sheetName = sheetParameter.getString(SHEET_NAME, StringKit.EMPTY); |
||||
if (StringKit.isBlank(sheetName)) { |
||||
sheetName = reportWorkBook.getReportName(sheetIndex); |
||||
} |
||||
resultWorkBook.addReport(sheetName, reportWorkBook.getReport(sheetIndex)); |
||||
} |
||||
} |
||||
|
||||
private HashMap<String, Object> getParameters(JSONArray param) { |
||||
if (param == null) { |
||||
return null; |
||||
} |
||||
ParameterProvider[] parameters = new ParameterProvider[param.size()]; |
||||
for (int i = 0; i < param.size(); i++) { |
||||
parameters[i] = Parameter.getParameterFromJson(param.getJSONObject(i)); |
||||
} |
||||
HashMap<String, Object> parametersMap = new HashMap<String, Object>(); |
||||
addPara2Map(parametersMap, parameters); |
||||
return parametersMap; |
||||
} |
||||
|
||||
private void addPara2Map(Map<String, Object> parametersMap, ParameterProvider[] parameters) { |
||||
if (parameters == null) { |
||||
return; |
||||
} |
||||
for (ParameterProvider parameter : parameters) { |
||||
if (parameter == null || parameter.getName() == null) { |
||||
return; |
||||
} |
||||
parametersMap.put(parameter.getName().toUpperCase(), parameter.getValue()); |
||||
} |
||||
} |
||||
|
||||
private void printErrorJSON(HttpServletResponse res) throws Exception { |
||||
JSONObject errorJSON = JSONObject.create(); |
||||
errorJSON.put("error_code", 1) |
||||
.put("error_msg", I18nKit.getLocText("Plugin-igqb_Licence_Expired")); |
||||
WebUtils.printAsJSON(res, errorJSON); |
||||
} |
||||
|
||||
private JSONObject getParams(HttpServletRequest req) throws IOException { |
||||
BufferedReader br = new BufferedReader(new InputStreamReader(NetworkHelper.getRequestInputStream(req), "utf-8")); |
||||
StringBuilder sb = new StringBuilder(); |
||||
String temp; |
||||
while ((temp = br.readLine()) != null) { |
||||
sb.append(temp); |
||||
} |
||||
br.close(); |
||||
return new JSONObject(sb.toString()); |
||||
} |
||||
} |
@ -0,0 +1,33 @@
|
||||
/* |
||||
* Copyright (C), 2015-2019 |
||||
* FileName: RequestHandlerBridge |
||||
* Author: xx |
||||
* Date: 2019/8/17 22:20 |
||||
* Description: RequestHandlerBridge |
||||
* History: |
||||
* <author> <time> <version> <desc> |
||||
*/ |
||||
package com.fr.plugin.igqb.service; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.stable.fun.Authorize; |
||||
|
||||
import static com.fr.plugin.igqb.LocaleFinder.PLUGIN_ID; |
||||
|
||||
/** |
||||
* 〈Function Description〉<br> |
||||
* 〈RequestHandlerBridge〉 |
||||
* |
||||
* @author xx |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Authorize(callSignKey = PLUGIN_ID) |
||||
public class RequestHandlerBridge extends AbstractHttpHandlerProvider { |
||||
@Override |
||||
public BaseHttpHandler[] registerHandlers() { |
||||
return new BaseHttpHandler[]{ |
||||
new ReportDataHandler() |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,35 @@
|
||||
/* |
||||
* Copyright (C), 2015-2019 |
||||
* FileName: URLAliasBridge |
||||
* Author: xx |
||||
* Date: 2019/8/17 22:21 |
||||
* Description: URLAliasBridge |
||||
* History: |
||||
* <author> <time> <version> <desc> |
||||
*/ |
||||
package com.fr.plugin.igqb.service; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractURLAliasProvider; |
||||
import com.fr.decision.webservice.url.alias.URLAlias; |
||||
import com.fr.decision.webservice.url.alias.URLAliasFactory; |
||||
import com.fr.stable.fun.Authorize; |
||||
|
||||
import static com.fr.plugin.igqb.LocaleFinder.PLUGIN_ID; |
||||
import static com.fr.plugin.igqb.service.ReportDataHandler.API_EXPORT; |
||||
|
||||
/** |
||||
* 〈Function Description〉<br> |
||||
* 〈URLAliasBridge〉 |
||||
* |
||||
* @author xx |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Authorize(callSignKey = PLUGIN_ID) |
||||
public class URLAliasBridge extends AbstractURLAliasProvider { |
||||
@Override |
||||
public URLAlias[] registerAlias() { |
||||
return new URLAlias[]{ |
||||
URLAliasFactory.createPluginAlias(API_EXPORT, API_EXPORT, false), |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,2 @@
|
||||
Plugin-igqb=Export Excel sheet Plugin |
||||
Plugin-igqb_Licence_Expired=Export Excel Sheet Plugin Licence Expired |
@ -0,0 +1,2 @@
|
||||
Plugin-igqb=Export Excel sheet Plugin |
||||
Plugin-igqb_Licence_Expired=Export Excel Sheet Plugin Licence Expired |
Loading…
Reference in new issue