当前位置:网站首页>[excelexport], Excel to Lua, JSON, XML development tool
[excelexport], Excel to Lua, JSON, XML development tool
2022-07-07 15:53:00 【Le_ Sam】
Text :
be based on https://github.com/monkey256/ExcelExport The development has been revised again ,
Compared with the old version :
1. The new version supports formula Export , Multilingual Export
2. Remove unnecessary functions , Optimize core code
3. Numerical verification
4. The description table and the numerical table are combined into one , Convenient view
5. Support inserting empty columns
6. Export two copies of client and server according to the defined fields
7. Language packs are handled independently , Generate multiple copies according to the language .lua file
The main function
1. Software specifications :
“ One click export ”
For all under the specified directory .xlsx And .xls The files are exported to the client under the output directory .lua With the server .xml file
“ Language pack export ”
key word 【Language】, When the corresponding file name is detected , Export multiple copies according to different languages .lua file
2. Start the instructions from the command line :
*** View the help interface *** -h|-help
Example : tablegen2.exe -h
*** One click export *** -p handyExp
Example : tablegen2.exe -i fullPath -o outputDir -p handyExp
*** Export according to the specified type *** -p xml|json|lua
Example : tablegen2.exe -i fullPath -o outputDir -p lua
using System;
using System.Collections.Generic;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.IO;
using NPOI.XSSF.UserModel;
using System.Collections;
using tablegen2.common;
namespace tablegen2.logic
{
public static class TableExcelReader
{
// def Table parameter placeholder index
private const int DEF_HEADER_INDEX = 3;
// data Table parameter index
private const int DATA_HEADER_INDEX = DEF_HEADER_INDEX + 1;
// data Table data index
private const int DATA_DATA_INDEX = DEF_HEADER_INDEX + 2;
// Read and parse according to the path xls
public static TableExcelData loadFromExcel(string filePath)
{
if (!File.Exists(filePath))
throw new Exception(string.Format("{0} file does not exist !", filePath));
var ext = Path.GetExtension(filePath).ToLower();
if (ext != ".xls" && ext != ".xlsx")
throw new Exception(string.Format(" Unrecognized file extension {0}", ext));
var headers = new List<TableExcelHeader>();
var rows = new List<TableExcelRow>();
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// analysis xls Document core module
var workbook = ext == ".xls" ? (IWorkbook)new HSSFWorkbook(fs) : (IWorkbook)new XSSFWorkbook(fs);
fs.Close();
_readDataFromWorkbook(workbook, headers, rows);
return new TableExcelData(headers, rows);
}
private static void _readDataFromWorkbook(IWorkbook wb, List<TableExcelHeader> defHeader, List<TableExcelRow> rows)
{
var dataSheet = _checkSheetValidity(wb, AppData.Config.SheetNameForData);
var defHeaderIdx = new ArrayList();
var dataList = new List<List<string>>();
// Check Sheet Whether there is an empty line
_checkSheetIsNullRow(dataSheet, AppData.Config.SheetNameForData);
// Read def
_readDefSheet(dataSheet, defHeader);
// Check data The first row defines the field data
_checkHeadersFromDataSheet(dataSheet, defHeader);
// Check data Whether the value in conforms to the specified type
_checkAllDataSheetValidity(dataSheet, defHeader);
// Check data The primary key ID Whether it is null or repeated
_checkDataSheetKeyUnique(dataSheet, defHeader, "Id");
// Read data
_readDataSheet(dataSheet, defHeader, rows);
}
private static ISheet _checkSheetValidity(IWorkbook wb, string name)
{
var sheet = wb.GetSheet(name);
if (sheet == null)
{
throw new Exception(string.Format(" workbook '{0}' non-existent ", name));
}
return sheet;
}
// Check Sheet Whether there is an empty line
private static void _checkSheetIsNullRow(ISheet sheet, string sheetName)
{
string errMsg = string.Empty;
for (int idxRow = 1; idxRow <= sheet.LastRowNum; idxRow++)
{
var rd = sheet.GetRow(idxRow);
if (rd == null)
{
errMsg = errMsg + string.Format(" workbook '{0}' pass the civil examinations {1} Behavioral emptiness \n", sheetName, (idxRow + 1).ToString());
}
}
if (!String.IsNullOrEmpty(errMsg))
{
throw new Exception(errMsg);
}
}
// Read def
private static void _readDefSheet(ISheet sheet, List<TableExcelHeader> headers)
{
string errMsg = string.Empty;
var rowList = new List<IRow>();
var strList = new List<string>();
for (int i = 0; i <= DEF_HEADER_INDEX; i++)
{
rowList.Add(sheet.GetRow(i));
strList.Add(string.Empty);
}
var maxCellNum = sheet.GetRow(0).LastCellNum;
for (int idx = 0; idx < maxCellNum; idx++)
{
for (int idxRow = 0; idxRow < rowList.Count; idxRow++)
{
if (rowList[idxRow] != null)
{
strList[idxRow] = _convertCellToString(rowList[idxRow].GetCell(idx));
}
}
Log.Msg(" analysis Def ==> Name【{0}】 Type【{1}】 ExpType【{2}】 Desc【{3}】", strList[0], strList[1], strList[2], strList[3]);
if (!string.IsNullOrEmpty(strList[0]) && !string.IsNullOrEmpty(strList[1]) && !string.IsNullOrEmpty(strList[2]))
{
var header = new TableExcelHeader();
header.FieldName = strList[0];
header.FieldType = strList[1].ToLower();
header.FieldExpType = strList[2];
header.FieldDesc = strList[3];
header.FieldIndex = -1;
headers.Add(header);
}
else if (!(string.IsNullOrEmpty(strList[0]) && string.IsNullOrEmpty(strList[1]) && string.IsNullOrEmpty(strList[2])))
{
errMsg = errMsg + string.Format(" workbook Def in [{0},{1}] or [{0},{2}] or [{0},{3}] Data is abnormally missing ! \n", _sheetNumToEng(idx), 1, 2, 3);
}
}
if (!String.IsNullOrEmpty(errMsg))
{
throw new Exception(errMsg);
}
// testing Def Does it include ID Field
if (headers.Find(a => a.FieldName == "Id") == null)
{
throw new Exception(string.Format(" workbook Def Does not exist in the Id Field !"));
}
}
// Read Data The first row defines the field data
private static void _checkHeadersFromDataSheet(ISheet sheet, List<TableExcelHeader> headers)
{
string errMsg = string.Empty;
var rd = sheet.GetRow(DATA_HEADER_INDEX); // Take the fifth line
for (int idxCell = 0; idxCell < rd.LastCellNum; idxCell++)
{
var cell = rd.GetCell(idxCell);
if (cell != null && !String.IsNullOrEmpty(cell.StringCellValue))
{
int HeadIdx = headers.FindIndex(item => item.FieldName.Equals(cell.StringCellValue));
if (HeadIdx != -1)
{
headers[HeadIdx].FieldIndex = idxCell;
}
else
{
// data The corresponding data is missing
errMsg = errMsg + string.Format(" workbook Data There is unmatched data in :'{0}' \n", cell.StringCellValue);
}
}
}
foreach (var list in headers)
{
if (list.FieldIndex == -1)
{
errMsg = errMsg + string.Format(" workbook Def There is unmatched data in :'{0}' \n", list.FieldName);
}
}
if (!String.IsNullOrEmpty(errMsg))
{
throw new Exception(errMsg);
}
}
// Check data Whether all values in conform to the specified type
private static void _checkAllDataSheetValidity(ISheet sheet, List<TableExcelHeader> headers)
{
//Log.Msg("LastRowNum {0}", sheet.LastRowNum.ToString());
string errMsg = string.Empty;
var rd = sheet.GetRow(DATA_HEADER_INDEX); // Take the fifth line
for (int idxHead = 0; idxHead < headers.Count; idxHead++)
{
errMsg = errMsg + _checkDataSheetKeyValidity(sheet, headers, headers[idxHead].FieldName);
}
if (!String.IsNullOrEmpty(errMsg))
{
throw new Exception(errMsg);
}
}
// Check data Whether the key value in matches the type
private static string _checkDataSheetKeyValidity(ISheet sheet, List<TableExcelHeader> headers, string key)
{
string errMsg = string.Empty;
int idx = headers.FindIndex(item => item.FieldName.Equals(key));
if (idx != -1)
{
var fieldType = headers[idx].FieldType;
var fieldIndex = headers[idx].FieldIndex;
var cellList = _getAllCellByIndex(sheet, fieldIndex);
for (int idxCell = 0; idxCell < cellList.Count; idxCell++)
{
var cell = cellList[idxCell];
var cType = cell.CellType;
bool isErr = false;
//Log.Msg("index:【{0},{1}】headType:【{2}】cellType:【{3}】toStr:【{4}】", fieldIndex, idxCell, fieldType, cType, _convertCellToString(cell));
// Ignore blank single cells (TEST)
if (cType == CellType.Blank)
{
continue;
}
switch (fieldType)
{
case "int":
if ((cType != CellType.Numeric) || (cType == CellType.Numeric && !StrRegex.IsInteger(cell.NumericCellValue.ToString())))
{
isErr = true;
}
break;
case "double":
if ((cType != CellType.Numeric) || (cType == CellType.Numeric && !StrRegex.IsNumber(cell.NumericCellValue.ToString())))
{
isErr = true;
}
break;
case "string":
//if (cType != CellType.String)
//{
// isErr = true;
//}
break;
case "formula":
if (cType != CellType.Formula)
{
isErr = true;
}
break;
case "bool":
if (cType != CellType.Boolean)
{
isErr = true;
}
break;
default:
isErr = true;
break;
}
if (isErr == true)
{
errMsg = errMsg + string.Format(" workbook Data in [{0},{1}]={3} Does not conform to or ExcelExport Temporary does not support {2} type \n", _sheetNumToEng(fieldIndex), idxCell + DEF_HEADER_INDEX + 3, fieldType, _convertCellToString(cell));
}
}
}
else
{
errMsg = errMsg + string.Format(" workbook Data Not found in {0} Primary key \n", key);
}
return errMsg;
}
// Check data Whether the key value in is null or repeated
private static void _checkDataSheetKeyUnique(ISheet sheet, List<TableExcelHeader> headers, string key)
{
string errMsg = string.Empty;
int idx = headers.FindIndex(item => item.FieldName.Equals(key));
if (idx != -1)
{
var ids = new HashSet<string>();
var cellList = _getAllCellByIndex(sheet, headers[idx].FieldIndex);
for (int idxCell = 0; idxCell < cellList.Count; idxCell++)
{
var cell = cellList[idxCell];
var idKey = _convertCellToString(cell);
if (String.IsNullOrEmpty(idKey))
{
errMsg = errMsg + string.Format(" workbook Data in Id Primary key No {0} The row value is empty \n", idxCell + DEF_HEADER_INDEX + 3);
}
else if (ids.Contains(idKey))
{
errMsg = errMsg + string.Format(" workbook Data in Id Primary key No {0} Line already exists :{1} \n", idxCell + DEF_HEADER_INDEX + 3, idKey);
}
ids.Add(idKey);
}
}
else
{
errMsg = errMsg + string.Format(" workbook Data Not found in {0} Primary key \n", key);
}
if (!String.IsNullOrEmpty(errMsg))
{
throw new Exception(errMsg);
}
}
// Read Data
private static void _readDataSheet(ISheet sheet, List<TableExcelHeader> headers, List<TableExcelRow> rows)
{
// Index from Data Data start
for (int idxRow = DATA_DATA_INDEX; idxRow <= sheet.LastRowNum; idxRow++)
{
var rd = sheet.GetRow(idxRow);
var ds = new List<string>();
for (int idxHead = 0; idxHead < headers.Count; idxHead++)
{
var val = _convertCellToString(rd.GetCell(headers[idxHead].FieldIndex));
ds.Add(val);
}
// Add excelRow
rows.Add(new TableExcelRow() { StrList = ds });
}
}
// Number to English
private static string _sheetNumToEng(int idx)
{
var cur = idx + 1 + 64;
string rowIex = string.Empty;
if (65 <= cur && cur <= 90)
{
byte[] btNumber = new byte[] { (byte)cur };
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
rowIex = asciiEncoding.GetString(btNumber);
}
else
{
rowIex = (idx + 1).ToString();
}
return rowIex;
}
// Get all data in a single column , Index from Data Data start
private static List<ICell> _getAllCellByIndex(ISheet sheet, int index)
{
var list = new List<ICell>();
for (int i = DATA_DATA_INDEX; i <= sheet.LastRowNum; i++)
{
var rd = sheet.GetRow(i);
// Single unit is NULL when , Manually assign an empty white space
if (rd.GetCell(index) == null) {
rd.CreateCell(index, CellType.Blank);
}
list.Add(rd.GetCell(index));
}
return list;
}
// Single unit to String
private static string _convertCellToString(ICell cell)
{
string r = string.Empty;
if (cell != null)
{
switch (cell.CellType)
{
// Boolean value
case CellType.Boolean:
r = cell.BooleanCellValue.ToString();
break;
// Numeric type
case CellType.Numeric:
r = cell.NumericCellValue.ToString();
break;
// Formula type
case CellType.Formula:
r = cell.NumericCellValue.ToString();
break;
// Default String
default:
r = cell.StringCellValue;
break;
}
}
return r;
}
}
}
Project download link :https://download.csdn.net/download/Le_Sam/12822484
边栏推荐
- Whole process analysis of unity3d rendering pipeline
- How to understand that binary complement represents negative numbers
- Three. JS introductory learning notes 18: how to export JSON files with Blender
- Getting started with webgl (2)
- What is Base64?
- [markdown grammar advanced] make your blog more exciting (IV: set font style and color comparison table)
- AB package details in unity (super detail, features, packaging, loading, manager)
- leetcode 241. Different Ways to Add Parentheses 为运算表达式设计优先级(中等)
- 招标公告:2022年云南联通gbase数据库维保公开比选项目(第二次)比选公告
- Gd32 F3 pin mapping problem SW interface cannot be burned
猜你喜欢
Actually changed from 408 to self proposition! 211 North China Electric Power University (Beijing)
深度之眼(六)——矩阵的逆(附:logistic模型一些想法)
【花雕体验】15 尝试搭建Beetle ESP32 C3之Arduino开发环境
Yunxiaoduo software internal test distribution test platform description document
Iterator and for of.. loop
Cocos creator collision and collision callback do not take effect
Monthly observation of internet medical field in May 2022
Cocos uses custom material to display problems
numpy--疫情数据分析案例
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
随机推荐
./ Functions of configure, make and make install
招标公告:2022年云南联通gbase数据库维保公开比选项目(第二次)比选公告
Please supervise the 2022 plan
The rebound problem of using Scrollview in cocos Creator
航运船公司人工智能AI产品成熟化标准化规模应用,全球港航人工智能/集装箱人工智能领军者CIMC中集飞瞳,打造国际航运智能化标杆
How does geojson data merge the boundaries of regions?
用手机在通达信上开户靠谱吗?这样炒股有没有什么安全隐患
leetcode 241. Different Ways to Add Parentheses 为运算表达式设计优先级(中等)
[quick start of Digital IC Verification] 24. AHB sramc of SystemVerilog project practice (4) (AHB continues to deepen)
持续创作,还得靠它!
The "go to definition" in VS2010 does not respond or prompts the solution of "symbol not found"
C4D learning notes 2- animation - timeline and time function
山东老博会,2022中国智慧养老展会,智能化养老、适老科技展
Clang compile link ffmpeg FAQ
无线传感器网络--ZigBee和6LoWPAN
深度之眼(六)——矩阵的逆(附:logistic模型一些想法)
15. Using the text editing tool VIM
20th anniversary of agile: a failed uprising
Introduction to pyGame games
webgl_ Graphic transformation (rotation, translation, zoom)