feat:提交

This commit is contained in:
2025-07-22 18:22:31 +08:00
parent 160bb294ca
commit 2ebb3e1abe
85 changed files with 36380 additions and 0 deletions

View File

@@ -0,0 +1,375 @@
export class List<Item> extends Array<Item>
{
/** 返回符合条件的第一个元素 */
first(fn: (item: Item) => boolean): Item
{
if (this.length == 0)
return null
for (const item of this)
{
if (fn(item))
return item
}
return null
}
/** 返回符合条件的最后一元素 */
last(fn: (t: Item) => boolean): Item
{
if (this.length == 0)
return null
for (let i = this.length - 1; i >= 0; i--)
{
if (fn(this[i]))
return this[i]
}
return null
}
/** 最大值 */
max<T>(fn: (item: Item) => T): T
{
let maxV: T
for (const i of this)
{
let v = fn(i)
if (maxV == null)
{
maxV = fn(i)
}
else
{
if (v > maxV)
{
maxV = v
}
}
}
return maxV
}
/** 最小值 */
min<T>(fn: (item: Item) => T): T
{
let minV: T
for (const i of this)
{
let v = fn(i)
if (minV == null)
{
minV = fn(i)
}
else
{
if (v < minV)
{
minV = v
}
}
}
return minV
}
/** 累加 */
sum(fn: (item: Item) => number): number
{
let v: number = 0
for (const t of this)
{
v = v + fn(t)
}
return v
}
/** 平均值 */
avg(fn: (item: Item) => number): number
{
if (this.length == 0)
return 0
let sum = this.sum(fn)
return sum / this.length
}
/** 满足条件的元素数量 */
count(fn: (item: Item) => number): number
{
if (this.length == 0)
return 0
let c = 0
for (const item of this)
{
if (fn(item))
c = c + 1
}
return c
}
FindMax<T>(fn: (item: Item) => T): Item
{
return this.reduce((a: Item, b: Item): Item => fn(a) > fn(b) ? a : b)
}
}
export class ArrayExt
{
/** 返回满足条件的元素数量 */
static count<Item>(list: Item[], fn: (item: Item) => boolean): number
{
if (list.length == 0)
return 0
let c = 0
for (const item of list)
{
if (fn(item))
c = c + 1
}
return c
}
/** 移除 */
static remove<Item>(list: Item[], obj: Item)
{
let index = list.findIndex(t => t == obj)
if (index == -1)
return
list.splice(index, 1)
}
/** 返回符合条件的第一个元素 */
static first<Item>(list: Item[], fn: (item: Item) => boolean, orderFn1: (item: Item) => number = null, orderFn2: (item: Item) => number = null): Item
{
if (list.length == 0)
return null
if (orderFn1 == null)
{
for (const item of list)
{
if (fn(item))
return item
}
return null
}
let minValue1: number
let minValue2: number
let minItem: Item
for (const item of list)
{
if (fn(item) == false)
continue
let v1 = orderFn1(item)
let v2 = orderFn2 != null ? orderFn2(item) : 0
if (minValue1 == null || v1 < minValue1 || (v1 == minValue1 && v2 < minValue2))
{
minValue1 = v1
minValue2 = v2
minItem = item
}
}
return minItem
}
/** 返回符合条件的最后一元素 */
static last<Item>(list: Item[], fn: (t: Item) => boolean, orderFn1: (item: Item) => number = null, orderFn2: (item: Item) => number = null): Item
{
if (list.length == 0)
return null
if (orderFn1 == null)
{
for (let i = list.length - 1; i >= 0; i--)
{
if (fn(list[i]))
return list[i]
}
return null
}
//
let maxValue1: number
let maxValue2: number
let maxItem: Item
for (const item of list)
{
if (fn(item) == false)
continue
let v1 = orderFn1(item)
let v2 = orderFn2 ? orderFn2(item) : 0
if (maxValue1 == null || v1 > maxValue1 || (v1 == maxValue1 && v2 > maxValue2))
{
maxValue1 = v1
maxValue2 = v2
maxItem = item
}
}
return maxItem
}
/** 取最大值 */
static max<T1, T2>(list: T1[], fn: (item: T1) => T2, whereF: (item: T1) => boolean = null, defaultV: T2 = null): T2
{
let maxV: T2
for (const i of list)
{
if (whereF && whereF(i) == false)
continue
let v = fn(i)
if (maxV == undefined)
{
maxV = fn(i)
}
else
{
if (v > maxV)
{
maxV = v
}
}
}
if (maxV != undefined)
return maxV
return defaultV
}
/** 最小值 */
static min<Item, T>(list: Item[], fn: (item: Item) => T, whereF: (item: Item) => boolean = null, defaultV: T = null): T
{
let minV: T
for (const i of list)
{
if (whereF && whereF(i) == false)
continue
let v = fn(i)
if (minV == undefined)
{
minV = v
}
else
{
if (v < minV)
{
minV = v
}
}
}
if (minV != undefined)
return minV
return defaultV
}
/** 累加 */
static sum<Item>(list: Item[], fn: (item: Item) => number, wn?: (item: Item) => boolean): number
{
let v: number = 0
for (const t of list)
{
if (wn && wn(t) == false)
continue
v = v + fn(t)
}
return v
}
/** 平均值 */
static avg<Item>(list: Item[], fn: (item: Item) => number): number
{
if (this.length == 0)
return 0
let sum = ArrayExt.sum(list, fn)
return sum / this.length
}
/** 排序 */
static sortBy<Item>(list: Item[], fn: (item: Item) => number, fn2: (item: Item) => number = null)
{
if (fn2 == null)
return list.sort((a: Item, b: Item): number => fn(a) - fn(b))
else
return list.sort((a: Item, b: Item): number => fn(a) == fn(b) ? (fn2(a) - fn2(b)) : fn(a) - fn(b))
}
/** 降序 排序 */
static sortByDescending<Item>(list: Item[], fn: (item: Item) => number)
{
list.sort((a: Item, b: Item): number => fn(b) - fn(a))
}
/** 排序成新的数组 */
static orderBy<Item>(list: Item[], fn: (item: Item) => number, fn2: (item: Item) => number = null): Item[]
{
let newList = list.concat([])
if (fn2 == null)
return newList.sort((a: Item, b: Item): number => fn(a) - fn(b))
else
return newList.sort((a: Item, b: Item): number => fn(a) == fn(b) ? (fn2(a) - fn2(b)) : fn(a) - fn(b))
}
/** 降序成新的数组 */
static orderByDescending<Item>(list: Item[], fn: (item: Item) => number, fn2: (item: Item) => number = null): Item[]
{
let newList = list.concat([])
if (fn2 == null)
return list.sort((a: Item, b: Item): number => fn(b) - fn(a))
else
return list.sort((a: Item, b: Item): number => fn(a) == fn(b) ? (fn2(b) - fn2(a)) : fn(b) - fn(a))
}
/** 分组 */
static groupBy<Item, gT>(list: Item[], fn: (item: Item) => gT): GroupItem<gT, Item>[]
{
let groups = new Array<GroupItem<gT, Item>>()
for (const item of list)
{
let key = fn(item)
let group = groups.find(t => t.key == key)
if (group == null)
{
group = new GroupItem(key)
groups.push(group)
}
group.push(item)
}
return groups
}
/**
* 选择
* let newObjectList = ArrayExt.Select(list,t=>({pA:t.name, pB:t.age + "_"+ t.month}) ) ;
*/
static Select<Item, rT>(list: Item[], fn: (item: Item) => rT): rT[]
{
let newList = new Array<rT>()
for (const t of list)
{
newList.push(fn(t))
}
return newList
}
/** 过来,并按顺序排序 */
static where<Item>(list: Item[], whereFn: (item: Item) => boolean, orderfn1: (item: Item) => number = null, orderfn2: (item: Item) => number = null): Item[]
{
let newList = list.filter(whereFn)
if (orderfn1 == null && orderfn2 == null)
return newList
return ArrayExt.sortBy(newList, orderfn1, orderfn2)
}
}
export class GroupItem<gT, Item>
{
key: gT
get count() { return this.list.length }
list: Item[]
constructor(k: gT)
{
this.key = k
this.list = []
}
push(d: Item)
{
this.list.push(d)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,490 @@
export class DxfWritor
{
layers: WeakSet<Layer>
activeLayer: Layer
lineTypes: WeakSet<LineType>
offX = 0
offY = 0 // 基点
constructor()
{
this.layers = new WeakSet()
this.activeLayer = null
this.lineTypes = new WeakSet()
for (let i = 0; i < DrawingType.LINE_TYPES.length; ++i)
{
this.addLineType(
DrawingType.LINE_TYPES[i].name,
DrawingType.LINE_TYPES[i].description,
DrawingType.LINE_TYPES[i].elements,
)
}
for (let i = 0; i < DrawingType.LAYERS.length; ++i)
{
this.addLayer(
DrawingType.LAYERS[i].name,
DrawingType.LAYERS[i].colorNumber,
DrawingType.LAYERS[i].lineTypeName,
)
}
this.setActiveLayer('0')
}
/**
* @param {string} name
* @param {string} description
* @param {Array} elements - if elem > 0 it is a line, if elem < 0 it is gap, if elem == 0.0 it is a
*/
addLineType(name, description, elements)
{
this.lineTypes[name] = new LineType(name, description, elements)
return this
}
addLayer(name, colorNumber, lineTypeName)
{
this.layers[name] = new Layer(name, colorNumber, lineTypeName)
return this
}
/** 设置当前图层 白=0, 红=1, 黄=2, 绿=3,CYAN=4,BLUE=5,MAGENTA=6 */
setActiveLayer(name)
{
this.activeLayer = this.layers[name]
return this
}
setOffset(x1, y1)
{
this.offX = x1
this.offY = y1
}
clear()
{
}
drawLine(x1, y1, x2, y2)
{
this.activeLayer.addShape(new Line(x1 + this.offX, y1 + this.offY, x2 + this.offX, y2 + this.offY))
return this
}
drawRect(x1, y1, w, h)
{
x1 = x1 + this.offX
y1 = y1 + this.offY
this.activeLayer.addShape(new Line(x1, y1, x1 + w, y1))
this.activeLayer.addShape(new Line(x1 + w, y1, x1 + w, y1 + h))
this.activeLayer.addShape(new Line(x1 + w, y1 + h, x1, y1 + h))
this.activeLayer.addShape(new Line(x1, y1 + h, x1, y1))
return this
}
/**
* @param {number} x1 - Center x
* @param {number} y1 - Center y
* @param {number} r - radius
* @param {number} startAngle - degree
* @param {number} endAngle - degree
*/
drawArc(x1, y1, r, startAngle, endAngle)
{
this.activeLayer.addShape(new Arc(x1 + this.offX, y1 + this.offY, r, startAngle, endAngle))
return this
}
/**
* @param {number} x1 - Center x
* @param {number} y1 - Center y
* @param {number} r - radius
*/
drawCircle(x1, y1, r)
{
this.activeLayer.addShape(new Circle(x1 + this.offX, y1 + this.offY, r))
return this
}
/**
* @param {number} x1 - x
* @param {number} y1 - y
* @param {number} height - Text height
* @param {number} rotation - Text rotation
* @param {string} value - the string itself
*/
drawText(x1, y1, height, rotation, value)
{
this.activeLayer.addShape(new Text(x1 + this.offX, y1 + this.offY, height, rotation, value))
return this
}
/**
* @param {Array} points - Array of points like [ [x1, y1,r], [x2, y2,r]... ]
*/
drawPolyline(points, isClose = false)
{
for (const p of points)
{
p.x += this.offX
p.y += this.offY
}
this.activeLayer.addShape(new Polyline(points, isClose))
return this
}
_getDxfLtypeTable()
{
let s = '0\nTABLE\n' // start table
s += '2\nLTYPE\n' // name table as LTYPE table
for (let lineTypeName in this.lineTypes)
{
s += this.lineTypes[lineTypeName].toDxfString()
}
s += '0\nENDTAB\n' // end table
return s
}
_getDxfLayerTable()
{
let s = '0\nTABLE\n' // start table
s += '2\nLAYER\n' // name table as LAYER table
for (let layerName in this.layers)
{
s += this.layers[layerName].toDxfString()
}
s += '0\nENDTAB\n'
return s
}
toDxfString()
{
let s = ''
// start section
s += '0\nSECTION\n'
// name section as TABLES section
s += '2\nTABLES\n'
s += this._getDxfLtypeTable()
s += this._getDxfLayerTable()
// end section
s += '0\nENDSEC\n'
// ENTITES section
s += '0\nSECTION\n'
s += '2\nENTITIES\n'
for (let layerName in this.layers)
{
let layer = this.layers[layerName]
s += layer.shapesToDxf()
// let shapes = layer.getShapes();
}
s += '0\nENDSEC\n'
// close file
s += '0\nEOF'
return s
}
}
namespace DrawingType
{
// AutoCAD Color Index (ACI)
// http://sub-atomic.com/~moses/acadcolors.html
export const ACI = {
LAYER: 0,
RED: 1,
YELLOW: 2,
GREEN: 3,
CYAN: 4,
BLUE: 5,
MAGENTA: 6,
WHITE: 7,
}
export const LINE_TYPES = [
{ name: 'CONTINUOUS', description: '______', elements: [] },
{ name: 'DASHED', description: '_ _ _ ', elements: [5.0, -5.0] },
{ name: 'DOTTED', description: '. . . ', elements: [0.0, -5.0] },
]
export const LAYERS = [
{ name: '0', colorNumber: ACI.WHITE, lineTypeName: 'CONTINUOUS' },
{ name: '1', colorNumber: ACI.RED, lineTypeName: 'CONTINUOUS' },
{ name: '2', colorNumber: ACI.YELLOW, lineTypeName: 'CONTINUOUS' },
{ name: '3', colorNumber: ACI.GREEN, lineTypeName: 'CONTINUOUS' },
{ name: '4', colorNumber: ACI.CYAN, lineTypeName: 'CONTINUOUS' },
{ name: '5', colorNumber: ACI.BLUE, lineTypeName: 'CONTINUOUS' },
{ name: '6', colorNumber: ACI.MAGENTA, lineTypeName: 'CONTINUOUS' },
]
}
export class LineType
{
name: string
description: string
elements: any[]
/**
* @param {string} name
* @param {string} description
* @param {Array} elements - if elem > 0 it is a line, if elem < 0 it is gap, if elem == 0.0 it is a
*/
constructor(name, description, elements)
{
this.name = name
this.description = description
this.elements = elements
}
/**
* @link https://www.autodesk.com/techpubs/autocad/acadr14/dxf/ltype_al_u05_c.htm
*/
toDxfString()
{
let s = '0\nLTYPE\n'
s += '72\n65\n'
s += '70\n64\n'
s += `2\n${this.name}\n`
s += `3\n${this.description}\n`
s += `73\n${this.elements.length}\n`
s += `40\n${this.getElementsSum()}\n`
for (let i = 0; i < this.elements.length; ++i)
{
s += `49\n${this.elements[i]}\n`
}
return s
}
getElementsSum()
{
let sum = 0
for (let i = 0; i < this.elements.length; ++i)
{
sum += Math.abs(this.elements[i])
}
return sum
}
}
export class Layer
{
name: string
colorNumber: string
lineTypeName: string
shapes: any[]
constructor(name, colorNumber, lineTypeName)
{
this.name = name
this.colorNumber = colorNumber
this.lineTypeName = lineTypeName
this.shapes = []
}
toDxfString()
{
let s = '0\nLAYER\n'
s += '70\n64\n'
s += `2\n${this.name}\n`
s += `62\n${this.colorNumber}\n`
s += `6\n${this.lineTypeName}\n`
return s
}
addShape(shape)
{
this.shapes.push(shape)
shape.layer = this
}
getShapes()
{
return this.shapes
}
shapesToDxf()
{
let s = ''
for (let i = 0; i < this.shapes.length; ++i)
{
s += this.shapes[i].toDxfString()
}
return s
}
}
export class Arc
{
x1: number
y1: number
r: number
startAngle: number
endAngle: number
layer: Layer
/**
* @param {number} x1 - Center x
* @param {number} y1 - Center y
* @param {number} r - radius
* @param {number} startAngle - degree
* @param {number} endAngle - degree
*/
constructor(x1, y1, r, startAngle, endAngle)
{
this.x1 = x1
this.y1 = y1
this.r = r
this.startAngle = startAngle
this.endAngle = endAngle
}
toDxfString()
{
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/line_al_u05_c.htm
let s = `0\nARC\n`
s += `8\n${this.layer.name}\n`
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
s += `40\n${this.r}\n50\n${this.startAngle}\n51\n${this.endAngle}\n`
return s
}
}
export class Circle
{
x1: number
y1: number
r: number
layer: Layer
/**
* @param {number} x1 - Center x
* @param {number} y1 - Center y
* @param {number} r - radius
*/
constructor(x1, y1, r)
{
this.x1 = x1
this.y1 = y1
this.r = r
}
toDxfString()
{
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/circle_al_u05_c.htm
let s = `0\nCIRCLE\n`
s += `8\n${this.layer.name}\n`
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
s += `40\n${this.r}\n`
return s
}
}
export class Line
{
x1: number
y1: number
x2: number
y2: number
layer: Layer
constructor(x1: number, y1: number, x2: number, y2: number)
{
this.x1 = x1
this.y1 = y1
this.x2 = x2
this.y2 = y2
}
toDxfString()
{
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/line_al_u05_c.htm
let s = `0\nLINE\n`
s += `8\n${this.layer.name}\n`
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
s += `11\n${this.x2}\n21\n${this.y2}\n31\n0\n`
return s
}
}
export class Polyline
{
points: any[]
isClose = false
layer: Layer
/**
* @param {Array} points - Array of points like [ [x1, y1,r], [x2, y2,r]... ]
*/
constructor(points, isClose)
{
this.points = points
this.isClose = isClose
}
toDxfString()
{
// https://www.autodesk.com/techpubs/autocad/acad2000/dxf/polyline_dxf_06.htm
// https://www.autodesk.com/techpubs/autocad/acad2000/dxf/vertex_dxf_06.htm
let s = `0\nPOLYLINE\n`
s += `8\n${this.layer.name}\n`
s += `66\n1\n70\n${this.isClose ? 1 : 0}\n`
for (let i = 0; i < this.points.length; ++i)
{
s += `0\nVERTEX\n`
s += `8\n${this.layer.name}\n`
s += `70\n0\n`
s += `10\n${this.points[i].x}\n20\n${this.points[i].y}\n42\n${this.points[i].r}\n`
}
s += `0\nSEQEND\n`
return s
}
}
export class Text
{
x1: number
y1: number
height: number
rotation: number
value: string
layer: Layer
/**
* @param {number} x1 - x
* @param {number} y1 - y
* @param {number} height - Text height
* @param {number} rotation - Text rotation
* @param {string} value - the string itself
*/
constructor(x1, y1, height, rotation, value)
{
this.x1 = x1
this.y1 = y1
this.height = height
this.rotation = rotation
this.value = value
}
toDxfString()
{
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/text_al_u05_c.htm
let s = `0\nTEXT\n`
s += `8\n${this.layer.name}\n`
s += `1\n${this.value}\n`
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
s += `40\n${this.height}\n50\n${this.rotation}\n`
return s
}
}

View File

@@ -0,0 +1,122 @@
export class textFile
{
/**保存单文件 text类型的 */
static saveFile(filename: string, content: string)
{
let blob = new Blob([content], { type: "text/plain;charset=utf-8" });
this.saveAs(filename, blob);
}
/**读取文件 选择文件组件,读取文档处理函数 */
static readFile(eleFile, fn_doText, fileType = "", fn_msg = null)
{
let noEleFile = !(eleFile);
if (noEleFile)
{
eleFile = document.createElement('input');
eleFile.type = 'file';
eleFile.accept = 'text/*';
eleFile.hidden = true;
document.body.appendChild(eleFile);
}
if (fileType && fileType != "") eleFile.accept = fileType;
let reader = new FileReader();
reader.onload = function (event)
{
let text = event.target["result"];
if (fn_doText) fn_doText(text);
};
// 选择文件
eleFile.onchange = function (event)
{
let file = event.target.files[0];
if (file)
{
reader.readAsText(file);
}
if (fn_msg != null)
{
fn_msg();
}
};
eleFile.click();
if (noEleFile)
{
document.body.removeChild(eleFile);
}
}
static getStringFromFile(eleFile, fileType = "", fn_msg = null): string
{
let noEleFile = !(eleFile);
if (noEleFile)
{
eleFile = document.createElement('input');
eleFile.type = 'file';
eleFile.accept = 'text/*';
eleFile.hidden = true;
document.body.appendChild(eleFile);
}
if (fileType && fileType != "") eleFile.accept = fileType;
let reader = new FileReader();
reader.onload = function (event)
{
let text = event.target["result"];
return text;
};
// 选择文件
eleFile.onchange = function (event)
{
let file = event.target.files[0];
if (file)
{
reader.readAsText(file);
}
if (fn_msg != null)
{
fn_msg();
}
};
eleFile.click();
if (noEleFile)
{
document.body.removeChild(eleFile);
}
return '';
}
/**保存文件 */
static saveAs(fileName: string, data: Blob)
{
// 创建隐藏的可下载链接
let eleLink = document.createElement('a');
eleLink.download = fileName;
eleLink.style.display = 'none';
eleLink.href = URL.createObjectURL(data);
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
}
static readFile2()
{
let rf = document.createElement('input');
rf.type = 'file';
rf.accept = 'text/*';
rf.hidden = true;
document.body.removeChild(rf);
}
}

View File

@@ -0,0 +1,118 @@
/** 文本表示的数字取值范围,比如 : "2,3,5-8" 表示
* () => 大于等于 小于等于
* [] => 大于 小于
*/
export class MaskedNumberRange {
maskedNumbers: any[]
constructor(strRs: string) {
let rs = []
let strs = strRs.split(',')
for (let str of strs) {
if (str.trim() == '')
continue
let n = Number(str)
let s_flag = 'in'
let e_flag = 'in'
if (!Number.isNaN(n)) {
rs.push({ s: n, e: n, s_flag, e_flag })
}
else {
let zys = str.split('-')
if (zys.length != 2)
continue
if (zys[0].trim() == '' || zys[1].trim() == '')
continue
let start :any = zys[0]
let end :any = zys[1]
if (zys[0].trim().includes('(')) {
s_flag = 'notIn'
start = start.replaceAll('(', '')
} else if (zys[0].trim().includes('[')) {
s_flag = 'in'
start = start.replaceAll('[', '')
}
if (start == 'x') {
s_flag = 'infinite'
}else{
start = Number(start)
}
if (zys[1].trim().includes(')')) {
e_flag = 'notIn'
end = end.replaceAll(')', '')
} else if (zys[1].trim().includes(']')) {
e_flag = 'in'
end = end.replaceAll(']', '')
}
if (end == 'x') {
e_flag = 'infinite'
}else{
end = Number(end)
}
let s = start // Number(zys[0])
let e = end //Number(zys[1])
rs.push({ s: s, e: e, s_flag, e_flag })
}
}
this.maskedNumbers = rs
}
/** 参数是否在给定范围内 */
isInRange(r: number): boolean {
let res = false
for (let se of this.maskedNumbers) {
if (se.s_flag == 'infinite') {
// 无穷 不判断
res = true
} else if (se.s_flag == 'notIn') {
if (r > se.s) {
res = true
}
} else if (se.s_flag == 'in') {
if (r >= se.s) {
res = true
}
}
if (res == true) {
let res1 = false
if (se.e_flag == 'infinite') {
res1 = true
} else if (se.e_flag == 'notIn') {
if (r < se.e) {
res1 = true
}
} else if (se.e_flag == 'in') {
if (r <= se.e) {
res1 = true
}
}
res = res && res1
}
if(res == true){
return true
}
// if (r > se.s && r < se.e)
// return true
}
return res
}
}

View File

@@ -0,0 +1,128 @@
/** 相等, 相差小于diff */
export function equal(a: number, b: number, diff = 0.001): boolean
{
return Math.abs(a - b) < diff
}
/** ab相差dis */
export function isDiffer(a: number, b: number, dis: number, diff = 0.001): boolean
{
let rdis = Math.abs(a - b)
return rdis > dis - diff && rdis < dis + diff
}
/** 两点间距离 */
export function getDis2(p1, p2): number
{
let x1 = p1.pointX || p1.X || p1.x || 0
let y1 = p1.pointY || p1.Y || p1.y || 0
let x2 = p2.pointX || p2.X || p2.x || 0
let y2 = p2.pointY || p2.Y || p2.y || 0
return getDis(x1, y1, x2, y2)
}
/** 两点间距离 */
export function getDis(x1: number, y1: number, x2: number, y2: number): number
{
let xt = x1 - x2
let yt = y1 - y2
return Math.sqrt(xt * xt + yt * yt)
}
/** 两点间弧度半径 */
export function getR(x1: number, y1: number, x2: number, y2: number, bul: number): number
{
if (bul == 0)
return 0
let d = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) / 2
return 0.5 * d * (1 + bul ** 2) / bul
}
/** 获取两点间的半径 */
export function getR2(p1, p2): number
{
let bul = p1.Curve || p1.bul || 0
if (bul == 0)
return 0
let x1 = p1.pointX || p1.X || p1.x
let y1 = p1.pointY || p1.Y || p1.y
let x2 = p2.pointX || p2.X || p2.x
let y2 = p2.pointY || p2.Y || p2.y
return getR(x1, y1, x2, y2, bul)
}
/** 截取小数点 */
export function round(n: number, bit = 3): number
{
if (bit < 1)
return n
let tt = 10 ** bit
return Math.round(n * tt) / tt
}
/**
* 获得四点p{x,y}形成的矩形{x,y,w,l};
* 不是矩形 返回null
*/
export function getRect(p0, p1, p2, p3): any
{
if (equal(p0.x, p1.x) == false && equal(p0.y, p1.y) == false)
return null
// 中心点
let xc = (p0.x + p1.x + p2.x + p3.x) / 4
let yc = (p0.y + p1.y + p2.y + p3.y) / 4
let dis0 = getDis(p0.x, p0.y, xc, yc)
let dis1 = getDis(p1.x, p1.y, xc, yc)
let dis2 = getDis(p2.x, p2.y, xc, yc)
let dis3 = getDis(p3.x, p3.y, xc, yc)
if (equal(dis0, dis1) && equal(dis0, dis2) && equal(dis0, dis3))
{
let x = Math.min(p0.x, p1.x, p2.x, p3.x)
let y = Math.min(p0.y, p1.y, p2.y, p3.y)
let w = Math.max(p0.x, p1.x, p2.x, p3.x) - x
let l = Math.max(p0.y, p1.y, p2.y, p3.y) - y
if (w < 0.01 || l < 0.01)
return null
return { x, y, w, l }
}
return null
}
/** 获取两点的直线的一般式方程AX+BY+C=0 ABC */
export function getLineABC(x1: number, y1: number, x2: number, y2: number)
{
let A = y2 - y1
let B = x1 - x2
let C = x2 * y1 - x1 * y2
return { A, B, C }
}
/** 获取点 p(x,y) 到两点的线的距离 */
export function getDis_PointLine(x1: number, y1: number, x2: number, y2: number, x: number, y: number)
{
let abc = getLineABC(x1, y1, x2, y2)
let aabb = Math.sqrt(abc.A * abc.A + abc.B * abc.B)
if (aabb == 0)
return 0
return Math.abs(abc.A * x + abc.B * y + abc.C) / aabb
}
/** 删除重复点 */
export function removeRepeatPoint(pts, fuzz = 0.01)
{
for (let n = pts.length - 1; n >= 0; n--) {
let p = n - 1
if (p < 0)
p = pts.length - 1
if (getDis2(pts[p], pts[n]) < fuzz)
pts.splice(n, 1)
}
}

View File

@@ -0,0 +1,170 @@
import { PlaceStyle,EdgeType } from '../../confClass.js'
// import { EdgeType } from '../../vo/enums/EdgeType.js'
/**
* 排版方式,返回排版后的[下右上左]所对应原始边 rt = [] 下0 右1 上2 左3
* 比如 rt[0] = 3 表示现在的下边是原始的左边
* rt[2] = 0 表示现在的上边是原始的下边
* @param placeStyle 放置方式
*/
export function getOriginalSides(placeStyle: PlaceStyle): number[]
{
// let orgSides = [0, 1, 2, 3];
let orgSides = [EdgeType.BOTTOM, EdgeType.RIGHT, EdgeType.TOP, EdgeType.LEFT]
switch (placeStyle)
{
case PlaceStyle.FRONT: // 正面
break
case PlaceStyle.FRONT_TURN_RIGHT: // 正面右转
orgSides[EdgeType.BOTTOM] = EdgeType.RIGHT
orgSides[EdgeType.RIGHT] = EdgeType.TOP
orgSides[EdgeType.TOP] = EdgeType.LEFT
orgSides[EdgeType.LEFT] = EdgeType.BOTTOM
break
case PlaceStyle.FRONT_TURN_BACK: // 正面后转
orgSides[EdgeType.BOTTOM] = EdgeType.TOP
orgSides[EdgeType.RIGHT] = EdgeType.LEFT
orgSides[EdgeType.TOP] = EdgeType.BOTTOM
orgSides[EdgeType.LEFT] = EdgeType.RIGHT
break
case PlaceStyle.FRONT_TURN_LEFT: // 正面左转
orgSides[EdgeType.BOTTOM] = EdgeType.LEFT
orgSides[EdgeType.RIGHT] = EdgeType.BOTTOM
orgSides[EdgeType.TOP] = EdgeType.RIGHT
orgSides[EdgeType.LEFT] = EdgeType.TOP
break
case PlaceStyle.BACK: // 反面
orgSides[EdgeType.BOTTOM] = EdgeType.BOTTOM
orgSides[EdgeType.RIGHT] = EdgeType.LEFT
orgSides[EdgeType.TOP] = EdgeType.TOP
orgSides[EdgeType.LEFT] = EdgeType.RIGHT
break
case PlaceStyle.BACK_TURN_RIGHT: // 反面右转
orgSides[EdgeType.BOTTOM] = EdgeType.LEFT
orgSides[EdgeType.RIGHT] = EdgeType.TOP
orgSides[EdgeType.TOP] = EdgeType.RIGHT
orgSides[EdgeType.LEFT] = EdgeType.BOTTOM
break
case PlaceStyle.BACK_TURN_BACK: // 反面后转
orgSides[EdgeType.BOTTOM] = EdgeType.TOP
orgSides[EdgeType.RIGHT] = EdgeType.RIGHT
orgSides[EdgeType.TOP] = EdgeType.BOTTOM
orgSides[EdgeType.LEFT] = EdgeType.LEFT
break
case PlaceStyle.BACK_TURN_LEFT: // 反面左转
orgSides[EdgeType.BOTTOM] = EdgeType.RIGHT
orgSides[EdgeType.RIGHT] = EdgeType.BOTTOM
orgSides[EdgeType.TOP] = EdgeType.LEFT
orgSides[EdgeType.LEFT] = EdgeType.TOP
break
default:
break
}
return orgSides
}
/**
* 返回原始边[下右上左] 放置后位置 rt = [,,,,]
* 例如 rt[0] = 3 表示原始下边,现在放置后的新位置是左边
* rt[2] = 0 表示原始上边,现在放置后的新位置是下边
* @param placeStyle 放置方式
*/
export function getPlacedSides(placeStyle: PlaceStyle): number[]
{
// let orgSides = [0, 1, 2, 3];
let orgSides = [EdgeType.BOTTOM, EdgeType.RIGHT, EdgeType.TOP, EdgeType.LEFT]
switch (placeStyle)
{
case PlaceStyle.FRONT: // 正面
break
case PlaceStyle.FRONT_TURN_RIGHT: // 正面右转
orgSides[EdgeType.BOTTOM] = EdgeType.LEFT
orgSides[EdgeType.RIGHT] = EdgeType.BOTTOM
orgSides[EdgeType.TOP] = EdgeType.RIGHT
orgSides[EdgeType.LEFT] = EdgeType.TOP
break
case PlaceStyle.FRONT_TURN_BACK: // 正面后转
orgSides[EdgeType.BOTTOM] = EdgeType.TOP
orgSides[EdgeType.RIGHT] = EdgeType.LEFT
orgSides[EdgeType.TOP] = EdgeType.BOTTOM
orgSides[EdgeType.LEFT] = EdgeType.RIGHT
break
case PlaceStyle.FRONT_TURN_LEFT: // 正面左转
orgSides[EdgeType.BOTTOM] = EdgeType.RIGHT
orgSides[EdgeType.RIGHT] = EdgeType.TOP
orgSides[EdgeType.TOP] = EdgeType.LEFT
orgSides[EdgeType.LEFT] = EdgeType.BOTTOM
break
case PlaceStyle.BACK: // 反面
orgSides[EdgeType.BOTTOM] = EdgeType.BOTTOM
orgSides[EdgeType.RIGHT] = EdgeType.LEFT
orgSides[EdgeType.TOP] = EdgeType.TOP
orgSides[EdgeType.LEFT] = EdgeType.RIGHT
break
case PlaceStyle.BACK_TURN_RIGHT: // 反面右转
orgSides[EdgeType.BOTTOM] = EdgeType.LEFT
orgSides[EdgeType.RIGHT] = EdgeType.TOP
orgSides[EdgeType.TOP] = EdgeType.RIGHT
orgSides[EdgeType.LEFT] = EdgeType.BOTTOM
break
case PlaceStyle.BACK_TURN_BACK: // 反面后转
orgSides[EdgeType.BOTTOM] = EdgeType.TOP
orgSides[EdgeType.RIGHT] = EdgeType.RIGHT
orgSides[EdgeType.TOP] = EdgeType.BOTTOM
orgSides[EdgeType.LEFT] = EdgeType.LEFT
break
case PlaceStyle.BACK_TURN_LEFT: // 反面左转
orgSides[EdgeType.BOTTOM] = EdgeType.RIGHT
orgSides[EdgeType.RIGHT] = EdgeType.BOTTOM
orgSides[EdgeType.TOP] = EdgeType.LEFT
orgSides[EdgeType.LEFT] = EdgeType.TOP
break
default:
break
}
return orgSides
}
/** 获取排版位置 */
export function getPlacePosition(x: number, y: number, width: number, length: number, placeStyle: PlaceStyle): any
{
let posX = x
let posY = y
switch (placeStyle)
{
case PlaceStyle.FRONT: // 正面
break
case PlaceStyle.FRONT_TURN_RIGHT: // 正面右转
posX = y
posY = width - x
break
case PlaceStyle.FRONT_TURN_BACK: // 正面后转
posX = width - x
posY = length - y
break
case PlaceStyle.FRONT_TURN_LEFT: // 正面左转
posX = length - y
posY = x
break
case PlaceStyle.BACK: // 反面
posX = width - x
posY = y
break
case PlaceStyle.BACK_TURN_RIGHT: // 反面右转
posX = y
posY = x
break
case PlaceStyle.BACK_TURN_BACK: // 反面后转
posX = x
posY = length - y
break
case PlaceStyle.BACK_TURN_LEFT: // 反面左转
posX = length - y
posY = width - x
break
default:
break
}
return { x: posX, y: posY }
}

View File

@@ -0,0 +1,152 @@
import gb2312 from './gb2312.json'
export class StringBase64 {
static ToBase64_gb2312(str: string): string {
let bin = this.toGB2312Bytes(str || '')
let str64 = this.encode(bin)
return str64
}
static _table = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/']
/** 将二进制转换成base64 */
static encode(bin: number[]): string {
let codes = []
let un = 0
un = bin.length % 3
if (un == 1)
bin.push(0, 0)
else if (un == 2)
bin.push(0)
for (let i = 2; i < bin.length; i += 3) {
let c = bin[i - 2] << 16
c |= bin[i - 1] << 8
c |= bin[i]
codes.push(this._table[c >> 18 & 0x3F])
codes.push(this._table[c >> 12 & 0x3F])
codes.push(this._table[c >> 6 & 0x3F])
codes.push(this._table[c & 0x3F])
}
if (un >= 1) {
codes[codes.length - 1] = '='
bin.pop()
}
if (un == 1) {
codes[codes.length - 2] = '='
bin.pop()
}
return codes.join('')
}
/** 将utf8 转成gb2312字符串 */
static toGb2312String(str1: string): string {
let substr = ''
let a = ''
let b = ''
let c = ''
let i = -1
i = str1.indexOf('%')
if (i == -1) {
return str1
}
while (i != -1) {
if (i < 3) {
substr = substr + str1.substr(0, i - 1)
str1 = str1.substr(i + 1, str1.length - i)
a = str1.substr(0, 2)
str1 = str1.substr(2, str1.length - 2)
if ((Number.parseInt(`0x${a}`) & 0x80) == 0) {
substr = substr + String.fromCharCode(Number.parseInt(`0x${a}`))
}
else if ((Number.parseInt(`0x${a}`) & 0xE0) == 0xC0) { // two byte
b = str1.substr(1, 2)
str1 = str1.substr(3, str1.length - 3)
let widechar = (Number.parseInt(`0x${a}`) & 0x1F) << 6
widechar = widechar | (Number.parseInt(`0x${b}`) & 0x3F)
substr = substr + String.fromCharCode(widechar)
}
else {
b = str1.substr(1, 2)
str1 = str1.substr(3, str1.length - 3)
c = str1.substr(1, 2)
str1 = str1.substr(3, str1.length - 3)
let widechar = (Number.parseInt(`0x${a}`) & 0x0F) << 12
widechar = widechar | ((Number.parseInt(`0x${b}`) & 0x3F) << 6)
widechar = widechar | (Number.parseInt(`0x${c}`) & 0x3F)
substr = substr + String.fromCharCode(widechar)
}
}
else {
substr = substr + str1.substring(0, i)
str1 = str1.substring(i)
}
i = str1.indexOf('%')
}
return substr + str1
}
private static _unicode2gb
static getUnicode2gb() {
if (this._unicode2gb == null) {
this._unicode2gb = gb2312
}
return this._unicode2gb
}
static toGB2312Bytes(str: string): number[] {
let unicode2gb = this.getUnicode2gb()
let res = []; let len = str.length
for (let i = 0; i < len; i++) {
let code = str.charCodeAt(i)
if (code <= 0x007F) {
res.push(code)
}
else {
let hex = unicode2gb[`0x${code.toString(16).toUpperCase()}`]
let gb = Number(hex)
if (Number.isNaN(gb))
gb = Number('0xA1F5')
let arr = []
while (gb > 0) {
arr.push(gb & 0xFF)
gb >>= 8
}
while (arr.length > 0) res.push(arr.pop())
}
}
return res
}
static fromGB2312Bytes(gb2312Bytes: number[]): string {
let unicode2gb = this.getUnicode2gb()
let res = []
// var i = 0
for (let i = 0; i < gb2312Bytes.length; i++) {
let code = gb2312Bytes[i]
if (code < 0xA1 || code > 0xFE || i + 1 == gb2312Bytes.length) {
res.push(String.fromCharCode(code))
continue
}
let c2 = gb2312Bytes[i + 1]
if (code < 0xA1 || code > 0xFE) {
res.push(String.fromCharCode(code))
continue
}
let g = c2 | code << 8
c2 = Number(unicode2gb[`0x${g.toString(16).toUpperCase()}`])
if (typeof c2 == 'undefined') {
res.push(String.fromCharCode(code))
continue
}
res.push(String.fromCharCode(c2))
i++
}
return res.join('')
}
}

View File

@@ -0,0 +1,82 @@
export class StringBuider
{
strings: string[]
constructor()
{
this.strings = []
}
/** 插入 */
Append(obj: any)
{
this.strings.push(obj)
}
/** 插入文本 */
AppendString(str: string) { this.strings.push(str) }
/** 格式化 插入 */
AppendFormat(str: string, ...arg: any[]): string
{
for (let i = 0; i < arg.length; i++)
{
let parent = `\\{${i}\\}`
let reg = new RegExp(parent, 'g')
str = str.replace(reg, arg[i])
}
this.strings.push(str)
return str
}
/** 添加一行(回车) */
AppendLine(str = '')
{
if (str != null)
{
this.AppendString(str)
}
}
/** 插入 */
Insert(index: number, ...strs)
{
if (strs.length == 0)
return
if (index > this.strings.length)
index = this.strings.length
if (index < 0)
index = 0
this.strings.splice(index, 0, ...strs)
}
/** 删除片段 */
Remove(startIndex: number, length: number): string[]
{
return this.strings.splice(startIndex, length)
}
/** 所有文本 */
ToString(): string
{
return this.strings.join('\r\n')
}
/** 清空 */
Clear() { this.strings = [] }
/** 容量 */
get size() { return this.strings.length }
/** 文本数 */
get Count() { return this.strings.length }
GetStringLength(): number
{
let length = 0
for (const str of this.strings)
{
length += str.length
}
return length
}
}

View File

@@ -0,0 +1,126 @@
export class StringFormat
{
/**
* 对Date的扩展将 Date 转化为指定格式的String
* 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符
* 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
* eg:
* (new Date()).pattern("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
* (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
* (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
* (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
* (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
*/
static Date(date: Date, fmt): string
{
let o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, // 小时
'H+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S': date.getMilliseconds(), // 毫秒
}
let week = {
0: '/u65e5',
1: '/u4e00',
2: '/u4e8c',
3: '/u4e09',
4: '/u56db',
5: '/u4e94',
6: '/u516d',
}
if (/(y+)/.test(fmt))
{
fmt = fmt.replace(RegExp.$1, (`${date.getFullYear()}`).substr(4 - RegExp.$1.length))
}
if (/(E+)/.test(fmt))
{
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '/u661f/u671f' : '/u5468') : '') + week[`${date.getDay()}`])
}
for (let k in o)
{
if (new RegExp(`(${k})`).test(fmt))
{
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : ((`00${o[k]}`).substr((`${o[k]}`).length)))
}
}
return fmt
}
/** 返回数字的固定小数点 123.00 */
static number(value: number, bit: number): string
{
return value?.toFixed(bit).toString()
}
static toFixed(value: number, bit: number = 3): number
{
let tt = 10 ** bit
return Math.round(value * tt) / tt
}
static filterIllegalChar(str: string): string
{
// var pattern = new RegExp("[/:*?'<>|\\]");
// var rs = "";
// for (var i = 0; i < str.length; i++)
// {
// rs = rs + str.substr(i, 1).replace(pattern, '');
// }
// return rs;
let rt = str.replace(/\\/g, '').replace(/\:/g, '').replace(/\*/g, '').replace(/\?/g, '').replace(/\"/g, '').replace(/\</g, '').replace(/\>/g, '').replace(/\|/g, '').replace(/\'/g, '')
return rt
}
/** 文本格式化 */
static format(str: string, ...args: any[]): string
{
let data = args
let tmpl = str
for (const item of tmpl.matchAll(/\{(.+?)\}/g))
{
let parts = item[1].split(',').map(i => i.trim())
let index = Number(parts[0])
let arg = data[index]
let val = (arg || '').toString() // 默认
if (arg instanceof Date) // 日期
{
let fm = 'MM-dd HH;mm'
if (parts.length > 1)
{
fm = parts[1]
}
val = this.Date(arg, fm)
}
if (parts.length > 1 && parts[1][0] === '#')
{
// {2,#3} -> 数字 转成3位 001,...023,
val = val.padStart(Number(parts[1].substring(1)), '0')
}
tmpl = tmpl.replace(item[0], val)
}
return tmpl
}
/** 实现右对齐,右边填充 (25,4,'*') => '25**' */
static PadEnd(num: number, totalWidth: number, paddingChar: string): string
{
let str = num.toString()
return str.padEnd(totalWidth, paddingChar[0])
}
/** 实现右对齐,左边填充 (25,4,'0') => '0025' */
static PadStart(num: number, totalWidth: number, paddingChar: string): string
{
let str = num.toString()
return str.padStart(totalWidth, paddingChar[0])
}
}

View File

@@ -0,0 +1,119 @@
export class textFile
{
/** 保存单文件 text类型的 */
static saveFile(filename: string, content: string)
{
let blob = new Blob([content], { type: 'text/plain;charset=utf-8' })
this.saveAs(filename, blob)
}
/** 读取文件 选择文件组件,读取文档处理函数 */
static readFile(eleFile, fn_doText, fileType = '', fn_msg = null)
{
let noEleFile = !(eleFile)
if (noEleFile)
{
eleFile = document.createElement('input')
eleFile.type = 'file'
eleFile.accept = 'text/*'
eleFile.hidden = true
document.body.appendChild(eleFile)
}
if (fileType && fileType != '')
eleFile.accept = fileType
let reader = new FileReader()
reader.onload = function (event)
{
let text = event.target.result
if (fn_doText)
fn_doText(text)
}
// 选择文件
eleFile.onchange = function (event)
{
let file = event.target.files[0]
if (file)
{
reader.readAsText(file)
}
if (fn_msg != null)
{
fn_msg()
}
}
eleFile.click()
if (noEleFile)
{
document.body.removeChild(eleFile)
}
}
static getStringFromFile(eleFile, fileType = '', fn_msg = null): string
{
let noEleFile = !(eleFile)
if (noEleFile)
{
eleFile = document.createElement('input')
eleFile.type = 'file'
eleFile.accept = 'text/*'
eleFile.hidden = true
document.body.appendChild(eleFile)
}
if (fileType && fileType != '')
eleFile.accept = fileType
let reader = new FileReader()
reader.onload = function (event)
{
let text = event.target.result
return text
}
// 选择文件
eleFile.onchange = function (event)
{
let file = event.target.files[0]
if (file)
{
reader.readAsText(file)
}
if (fn_msg != null)
{
fn_msg()
}
}
eleFile.click()
if (noEleFile)
{
document.body.removeChild(eleFile)
}
return ''
}
/** 保存文件 */
static saveAs(fileName: string, data: Blob)
{
// 创建隐藏的可下载链接
let eleLink = document.createElement('a')
eleLink.download = fileName
eleLink.style.display = 'none'
eleLink.href = URL.createObjectURL(data)
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
// 然后移除
document.body.removeChild(eleLink)
}
static readFile2()
{
let rf = document.createElement('input')
rf.type = 'file'
rf.accept = 'text/*'
rf.hidden = true
document.body.removeChild(rf)
}
}

View File

@@ -0,0 +1,138 @@
import { saveAs } from 'file-saver'
import type { ZipProvider } from '../zip.js'
import { DefaultZipProvider, FileInfo } from '../zip.js'
import { StringBuider } from './StringBuidler.js'
// import { textFile } from './File';
import { StringBase64 } from './StringBase64.js'
export class FileZip
{
zipName: string
// zip对象
private zip: ZipProvider = DefaultZipProvider()
// 文件数据
private stringBuider: StringBuider
constructor()
{
this.stringBuider = new StringBuider()
this.SetZipFileName('')
}
/** 设置zip文件名 */
SetZipFileName(_name: string)
{
this.zipName = _name
}
getZipFileName()
{
return this.zipName
}
PushBlobFile(fileName: string, content)
{
let newFile = new FileInfo(fileName, content, false)
newFile.binary = true
this.zip.addFile(newFile)
}
// /**添加文件 */
// PushFile(fileName: string, fileText: string, isBase64 = false, isgb2312 = false, isUtf8Bom=false)
// {
// if (isgb2312)
// {
// isBase64 = true;
// fileText = StringBase64.ToBase64_gb2312(fileText);
// }
// if(isUtf8Bom)
// {
// fileText = String.fromCharCode(parseInt("0xFEFF")) + fileText;
// }
// let newFile = new FileInfo(fileName, fileText, isBase64);
// this.zip.addFile(newFile);
// }
/** 添加文件 fileName文件名 fileText文件内容 isBase64是否base64 encoding编码格式(gb2312, utf8bom) */
PushFile(fileName: string, fileText: string, isBase64 = false, encoding: string = 'gb2312')
{
if (encoding == 'gb2312')
{
isBase64 = true
fileText = StringBase64.ToBase64_gb2312(fileText)
}
if (encoding == 'utf8bom')
{
fileText = String.fromCharCode(Number.parseInt('0xFEFF')) + fileText
}
let newFile = new FileInfo(fileName, fileText, isBase64)
this.zip.addFile(newFile)
}
pushFile_withBom(fileName: string, fileText: string)
{
this.PushFile(fileName, fileText, false, 'utf8bom')
}
PushFile_GB2312(fileName: string, fileText: string)
{
this.PushFile(fileName, fileText, false, 'gb2312')
}
/** 新建文件 */
NewFile()
{
this.stringBuider.Clear()
}
/** 推送文本到缓存区 */
AppentText(comment: string)
{
this.stringBuider.Append(comment)
}
// //将缓存区的文本 保存起来
// SaveFile(fileName: string, isgb2312: boolean = false, isutf8bom = false)
// {
// let fileText = this.stringBuider.ToString();
// this.stringBuider.Clear();
// this.PushFile(fileName, fileText, false, isgb2312, isutf8bom);
// }
// 将缓存区的文本 保存起来
SaveFile(fileName: string, encoding: string = 'gb2312')
{
let fileText = this.stringBuider.ToString()
this.stringBuider.Clear()
this.PushFile(fileName, fileText, false, encoding)
}
// 下载zip文件
async Download(zipName = '')
{
let content = await this.zip.saveAsync()
// textFile.saveAs(FileZip.zipName,content);
let name = zipName || this.zipName
saveAs(content, name)
}
static WriteFile(fname: string, data: BlobPart)
{
let blob = new Blob([data], { type: 'octet/stream' })
let download = document.createElement('a')
download.download = fname
download.href = window.URL.createObjectURL(blob)
download.style.display = 'none'
download.onclick = function ()
{
document.body.removeChild(download)
}
document.body.appendChild(download)
download.click()
};
}
export { FileInfo }

File diff suppressed because it is too large Load Diff