当前位置:网站首页>[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
边栏推荐
- 深度之眼(七)——矩阵的初等变换(附:数模一些模型的解释)
- Do not use memset to clear floating-point numbers
- Three. JS introduction learning notes 12: the model moves along any trajectory line
- AB package details in unity (super detail, features, packaging, loading, manager)
- nodejs package. JSON version number ^ and~
- When opening the system window under UE4 shipping, the problem of crash is attached with the plug-in download address
- OpenGL's distinction and understanding of VAO, VBO and EBO
- Clang compile link ffmpeg FAQ
- Use of SVN
- ./ Functions of configure, make and make install
猜你喜欢

How to create Apple Developer personal account P8 certificate
![[quick start of Digital IC Verification] 25. AHB sramc of SystemVerilog project practice (5) (AHB key review, key points refining)](/img/78/29eb8581e9a8fb4c6c7e1e35ad7adc.png)
[quick start of Digital IC Verification] 25. AHB sramc of SystemVerilog project practice (5) (AHB key review, key points refining)

After UE4 is packaged, mesh has no material problem

Shipping companies' AI products are mature, standardized and applied on a large scale. CIMC, the global leader in port and shipping AI / container AI, has built a benchmark for international shipping

C4D learning notes 3- animation - animation rendering process case

过度依赖补助,大客户收款难,冲刺“国产数据库第一股”的达梦后劲有多足?

Three. JS introductory learning notes 00: coordinate system, camera (temporarily understood)
![[wechat applet] Chapter (5): basic API interface of wechat applet](/img/63/e819113c7c93e273525bc850892972.png)
[wechat applet] Chapter (5): basic API interface of wechat applet

Syntax of generator function (state machine)

How does geojson data merge the boundaries of regions?
随机推荐
Apache Doris刚“毕业”:为什么应关注这种SQL数据仓库?
Steps to create P8 certificate and warehousing account
Numpy --- basic learning notes
【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
Webcodecs parameter settings -avc1.42e01e meaning
[quick start of Digital IC Verification] 18. Basic grammar of SystemVerilog learning 5 (concurrent threads... Including practical exercises)
无线传感器网络--ZigBee和6LoWPAN
Cut ffmpeg as needed, and use emscripten to compile and run
喜讯!科蓝SUNDB数据库与鸿数科技隐私数据保护管理软件完成兼容性适配
Shader Language
nodejs package. JSON version number ^ and~
HW primary flow monitoring, what should we do
有钱人买房就是不一样
用手机在通达信上开户靠谱吗?这样炒股有没有什么安全隐患
[quick start of Digital IC Verification] 20. Basic grammar of SystemVerilog learning 7 (coverage driven... Including practical exercises)
Function: JS Click to copy content function
Numpy -- epidemic data analysis case
10 schemes to ensure interface data security
Learn good-looking custom scroll bars in 1 minute
20th anniversary of agile: a failed uprising