• 产品与技术
    • 低代码
    • 活字格低代码平台
    • 低代码技术
    • 智能报表
    • Wyn(商业智能软件)
    • ActiveReportsJS(纯前端报表控件)
    • ActiveReports(.NET报表控件)
    • 报表模板库
    • 表格控件
    • SpreadJS(纯前端表格控件)
    • GcExcel(服务端表格组件)
    • Spread .NET(.NET表格控件)
    • 葡萄城表格技术
    • 控件套包
    • GrapeCity Documents(服务端文档组件库)
    • WijmoJS(前端UI组件库)
    • ComponentOne Enterprise(.NET控件集)
  • 客户与案例
    • 典型客户
    • 成功案例
    • 用户访谈
  • 伙伴与生态
    • 合作伙伴网络
    • 葡萄城市场
    • 葡萄城与国产化
    • 活字格用友客开工具
  • 技术服务
    • 技术服务体系
    • 产品培训
    • 技术社区(GCDN)
    • 新手训练营
    • 技术认证体系
    • 金牌服务
    • 技术博客
  • 品牌活动
    • 葡萄城公开课
    • 品牌战略发布会
    • 赋能开发者高峰论坛
    • 企业级低代码发展研讨会
    • 企业级低代码应用大赛
    • 表格技术研讨会
  • 了解葡萄城
    • 关于葡萄城
    • 葡萄城简介
    • 愿景使命
    • 企业理念
    • 企业文化
    • 研发与创新
    • 荣誉奖项
    • 加入我们
    • 新闻中心
    • 葡萄城动态
    • 产品动态
    • 业务资讯
    • 校企合作
  • 关于葡萄城

    • 了解葡萄城
    • 愿景使命
    • 企业理念
    • 新闻中心
    • 荣誉奖项
    • 加入我们
    • 联系方式
返回新闻中心

服务端表格组件GcExcel V5.0 Update2发布,提供了更为强大的表单控制API

2022.09.14

近日,葡萄城服务端表格组件 GcExcel (GrapeCity Documents for Excel )正式发布 V5.0 Update2 更新。

随着企业信息化需求的深入,越来越多的用户选择了SpreadJS + GcExcel的类Excel全栈解决方案,利用GcExcel 天然与 SpreadJS 前后端兼容的能力,以及遥遥领先同类产品的功能和性能,可在不依赖 Office、POI 和第三方软件的情况下,为您的应用程序提供在线文档的前后端数据同步、在线填报与服务端批量导出与打印,以及类 Excel 报表模板设计与服务端高性能处理等全栈的解决方案。

GcExcel V5.0 Update2 添加了Excel表单控制的新API,对数据模板语言进行了持续增强,并在图表、透视表等多个方面进行了改进。

在我们详细介绍 GcExcel V5.0 Update1的新特性之前,欢迎您移步前往至葡萄城官网下载最新版产品安装包,以便同步体验。

以下是本次发布的新特性内容:

添加 Excel 表单控件的新 API

在电子表格中收集和呈现数据的一种方法是通过添加到工作表的表单控件。列表框、复选框和按钮等控件有助于构建工作表并管理其数据。

GcExcel 现在支持 API 以编程方式添加 Excel 表单控件。您可以使用标准表单控件创建 Excel 表单、对其进行自定义、从用户那里收集数据或以编程方式检索表单控件值。此外,如果您的多个 Excel 电子表格包含表单控件,则电子表格可以加载到 GcExcel 对象模型中,并且可以修改表单控件。

GcExcel 引入了 IControlCollection,它添加了IControl类型的表单控件的所有通用成员 。您可以使用 Worksheet.Controls 添加或访问控件。支持以下控件:

  • Button
  • DropDown
  • CheckBox
  • Spinner
  • ListBox
  • OptionButton
  • GroupBox
  • Label
  • ScrollBar

有了这种支持,您还可以使用以下功能 -

每个控件都有自己的一组属性。您可以使用每个控件的特定 API 进行设置。例如,以下代码显示了如何设置特定于按钮控件的属性:

[code]
var workbook = new GrapeCity.Documents.Excel.Workbook();       
IWorksheet ws = workbook.Worksheets["Sheet1"];

var button = ws.Controls.AddButton(50, 30, 120, 40);
button.Text = "Submit";
button.PrintObject = true;
button.HorizontalTextAlignment = HorizontalAlignment.Center;
button.VerticalTextAlignment = VerticalAlignment.Center;

// Save to an excel file
workbook.Save("ButtonsBasicUsage.xlsx");
[/code]

  • 修改表单控件和表单控件值 - 使用 Worksheet.Controls 集合访问控件。 CheckBox、OptionButton、ListBox、DropDown 和 Scrollbar 表单控件的LinkedCell 属性有助于将控件的值绑定到链接单元格,反之亦然。您可以使用 LinkedCell 属性获取控件的值
  • 将表单控件用作 Shapes - 一个新选项, FormControl 已添加到 ShapeType 枚举,它可以检查表单控件是否为 Shape 类型。此外,使用 .ShapeRange 来使用表单控件上的某些形状功能,例如复制控件形状或复制单元格上的形状
  • 通过 Excel I/O 和 JSON I/O 使用表单控件
  • 导出为 PDF、HTML 和图像(导出为图像)

GcExcel 模板增强

分页模板

如果您有一个特定的模板,您希望页面上的行数固定,并且需要在以下工作表上重复相同的布局,您可以选择将工作簿分页到单独的工作表中。GcExcel 模板引入了“ TemplateOptions.PaginationMode”,这是一个全局布尔属性,当它为真时,可以将工作簿分页到单独的工作表中。同时,如果 false 将遵循模板布局和分页的传统规则。如果为 true,您可以定义新的 CountPerPage 属性 (CP) 用于需要重复数据的单元格。该属性将限制页面上生成的模板单元格的实例(记录)数量。当记录数超过 CP 的值时,会自动创建(或分页)一个新的工作表,其布局与模板相同。“CountPerPage”属性是指工作表上分组记录的计数。

以下快照显示 CP 值为 10,为模板单元设置。FM=O 表示当模板单元展开时,新实例将覆盖下面的单元。

在某些条件下 CountPerPage (CP) 属性将起作用。例如,当 Group (G) 属性设置为 Normal/Merge/Repeat时,记录被分组,count 是指创建的组数。如果 Group (G) 属性设置为 List,则记录不分组,Count 指的是实际记录数。

模板语言的调试模式

现在不再需要打开原始模板文件来检查模板是否正确展开。GcExcel 支持在 TemplateOptions 中定义名称 TemplateOptions.DebugMode 。当 DebugMode 为真时,原始模板工作表将出现在工作表 1 中,紧挨着展开的模板工作表 2。

支持图表 - 数据表

图表中的数据表有助于方便地查看/分析数据。在 Excel 中,数据表显示在 Excel 图表下方。这特别有用,因此可以一起分析数据和图表,而不是滚动到工作表或其他工作表中的不同位置以将图表数据与源数据匹配。为了帮助解决这个问题,GcExcel 引入了两个新属性 - IChart.HasDataTable 设置 true 或 false,是否将数据表添加到图表,IChart.DataTable 表示图表的数据表,它可以提供各种选项来设置数据表,如字体、格式、显示图例键等。

代码后快照中的数据表是使用新 API 添加的。数据表的格式可以自定义。看看下面的代码:

[code]
IWorksheet worksheet = workbook.Worksheets[0];

// Set data.
worksheet.Range["A1:C3"].Value = new object[,]
{
    {"BUDGET TOTALS", "ESTIMATED", "ACTUAL"},
    {"Income", 63300, 57450},
    {"Expenses", 54500, 49630}
};

//Create chart.
GrapeCity.Documents.Excel.Drawing.IShape shape = worksheet.Shapes.AddChart(GrapeCity.Documents.Excel.Drawing.ChartType.ColumnClustered, 250, 0, 350, 250);
shape.Chart.SeriesCollection.Add(worksheet.Range["A1:C3"]);
shape.Chart.ChartTitle.Text = "Estimated vs Actual";

//Display the data table.
shape.Chart.HasDataTable = true;

//Config the data table.
GrapeCity.Documents.Excel.Drawing.IDataTable datatable = shape.Chart.DataTable;
datatable.Format.Line.Color.ObjectThemeColor = ThemeColor.Accent6;
datatable.Font.Color.ObjectThemeColor = ThemeColor.Accent2;
datatable.Font.Size = 9;

// Save to an excel file
workbook.Save("chartdatatable.xlsx");
[/code]

在数据透视表中添加计算项

计算项有助于在数据透视表中添加自定义公式,对源数据中不存在的其他项执行自定义计算。GcExcel 引入了以下 API:

  • IPivotField.CalculatedItems() 获取CalculatedItems 集合,表示指定数据透视表字段中的所有计算项
  • ICalculatedItems.Add(string name, string formula) 创建一个新的计算项
  • ICalculatedItems.Remove(string name) 按名称删除计算字段
  • IPivotItem.Formula 获取或设置计算项目公式

如果数据透视表单元格中的值受两个或多个计算项的影响,则该值由求解顺序中的最后一个公式确定。使用 GcExcel,您可以使用以下 API 设置求解顺序:

  • IPivotFormula 是一个表示内容的对象,并解决了计算项的顺序
  • 使用 IPivotTable.IPivotFormulas() 获取 IPivotFormula 集合,该集合表示 指定数据透视表字段中的所有IPivotFormula
  • 使用 IPivotFormula.Index{get;set;} 获取或设置当前 PivotFormula的索引

下面的电子表格将国家和产品设置为计算项。'Country' 计算项添加了属于同一大陆的国家/地区的销售额,而 Product Calculated Item 将所有价值为 2500 美元的产品设置为 iPhone13,之后将此类项目的 Visible 设置为 False。

[code]
ICalculatedItems countryCalcItems = calculatedItemTable.PivotFields["Country"].CalculatedItems();
ICalculatedItems productCalcItems = calculatedItemTable.PivotFields["Product"].CalculatedItems();

// add some calculated items
countryCalcItems.Add("Oceania", "=Australia+NewZealand");
countryCalcItems.Add("Europe", "=France+Germany");
countryCalcItems.Add("America", "=Canada");

productCalcItems.Add("IPhone 13", "=2500");

// hide the duplicate normal item.
IPivotItems countrys = calculatedItemTable.PivotFields["Country"].PivotItems;
countrys["United Kingdom"].Visible = false;
countrys["United States"].Visible = false;

IPivotItems products = calculatedItemTable.PivotFields["Product"].PivotItems;
products["IPhone 13"].Visible = false;
calculatedItemSheet.Range["A:I"].AutoFit();

calculatedItemSheet.Activate();

// Save to an excel file
workbook.Save("Calculateditem.xlsx");
[/code]

在数据绑定中支持 JSON 作为 DataSource

您现在可以使用 JSON 字符串作为数据源绑定 Excel 电子表格。worksheet.DataSource 现在可以直接绑定到 接受 JSON 字符串作为数据源的JsonDataSource类。以下示例代码从 JSON 文件导入数据并将其绑定到工作表:

[code]
string jsonStr = "[{\"name\":\"jack\",\"age\":12},{\"name\":\"alice\",\"age\":25}]";
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.DataSource = new JsonDataSource(jsonStr);
worksheet.Range["A1"].BindingPath = "name";
workbook.Save("DataSource.xlsx");
[/code]

自定义函数中的 IsVolatile 属性支持

使用自定义函数时,GcExcel 将具有相同名称和参数的公式缓存存储在同一列中。这使得相同的公式在同一列中只计算一次。 GcExcel 在定义自定义函数时支持 IsVolatile布尔属性。该属性将控制在使用自定义函数时是否使用缓存。

以下示例演示如何创建自定义函数以生成 GUID。要每次生成唯一的 GUID,自定义函数不应使用缓存。因此,示例代码将 IsVolatile 属性设置为 true ,以便在每次调用时生成一个新的 GUID。

[code]
//create a new workbook
var workbook = new GrapeCity.Documents.Excel.Workbook();

GrapeCity.Documents.Excel.Workbook.AddCustomFunction(new GeneralID());

IWorksheet worksheet = workbook.Worksheets[0];
worksheet.Range["A1"].Formula = "GeneralID()";
var valueA1Before = worksheet.Range["A1"].Value;
worksheet.Range["A2"].Formula = "GeneralID()";
// A1's value has changed.
var valueA1After = worksheet.Range["A1"].Value;

/* Implementation of GeneralID

public class GeneralID : CustomFunction
{
    public GeneralID() : base("GeneralID", FunctionValueType.Object)
    {
        this.IsVolatile = true;
    }

    public override object Evaluate(object[] arguments, ICalcContext context)
    {
        return Guid.NewGuid().ToString("N");
    }
}

*/
[/code]

获得准确的范围边界

GcExcel .NET 添加了新的 CellInfo.GetAccurateRangeBoundary(..) 方法,该方法返回比 RectangleF 更准确的范围边界值。

以下代码获取范围的准确范围边界并在该确切位置添加形状。

[code]
// Get the absolute location and size of the Range["G1"] in the worksheet.
IRange range = worksheet.Range["F1:G1"];
RectangleF rect = GrapeCity.Documents.Excel.CellInfo.GetAccurateRangeBoundary(range);
// Add the image to the Range["G1"]
System.IO.Stream stream = this.GetResourceStream("logo.png");
worksheet.Shapes.AddPictureInPixel(stream, GrapeCity.Documents.Excel.Drawing.ImageType.PNG, rect.X, rect.Y, rect.Width, rect.Height);

// Save to an excel file
workbook.Save("getrangeboundary.xlsx");
[/code]

电子表格中的 SVG 图像支持

GcExcel 添加了 IShapes.AddPicureInPixel(..) 方法以添加 SVG 格式的图像。另外,ToImage(..) 方法支持导出为 SVG 图片的如下:

  • 使用 IRange.ToImage(string filename) 方法将范围导出为 SVG 图片
  • 使用 ISheet.ToImage(string filename) 方法将工作表导出为 SVG 图片
  • 使用 IShape.ToImage(string filename) 方法将形状导出为 SVG 图片

GcExcel 还将在以下情况下支持带有 SVG 图像的电子表格:

  • 无损导入导出excel文件
  • JSON 输入/输出
  • 导出为 PDF/HTML/图像文件

注意:要在 Java 中使用带有 GcExcel API 的 SVG 图像,扩展包 batik (1.14) 和 gcexcel-extension-5.2.0.jar 应该包含在项目中。

新的 Excel 函数

LET 函数

在您的电子表格中,您可能使用了多个可能很复杂的公式。LET 函数将用户友好的名称应用于范围/单元格或计算,并有助于提高公式计算性能。重复计算的冗长公式只能计算一次,并且可以用易于理解的名称存储结果。此名称可以在 LET 函数中进一步使用,只计算一次,稍后再使用结果。您不再需要记住引用的底层逻辑。GcExcel 将此 LET 函数添加到其 支持的 Functions列表中。如果多个工作表重复重复计算,您可以更新这些公式以使用 LET 函数。下面给出了对电子表格进行这种改进的一个示例。

在上面的示例中,LET 函数通过使用 LET 函数并将 VLOOKUP 的输出定义为 'name' 和 'points' 变量并在公式中重新使用它们,将 VLOOKUP 的计算次数从 4 次减少到 2 次。

下面的代码展示了如何在代码中设置函数:

[code]
ws.Range["$F$9"].Formula2 = "=LET(name,VLOOKUP($G$5,$B$5:$D$16,2,0),points,VLOOKUP($G$5,$B$5:$D$16,3,0),"Ho, "&name&", you have "&points&" points. "IF(points>300, "Great job, "&name&"!",""))
[/code]

GetPivotData 公式支持溢出数据

在上一个版本中,GcExcel 引入了 GETPIVOTDATA(...) 函数和新的 IRange.GenerateGetPivotDataFunction(IRange destination = null) 方法来为不同的工作表生成 GETPIVOTDATA 函数。

在 v5.2 中,我们扩展了此函数的功能,以支持类似于动态数组公式的溢出数据。该语法现在支持数组项和引用 - “ =GETPIVOTDATA(data_field, pivot_table, [field1, item1, field2, item2], ...)”。 因此,在下面的示例中,使用 GcExcel 在其中一个单元格中设置的 GETPIVOTDATA 函数将两个城市一起放入数组 {'New York', 'Boston'} 中,以便从数据透视表中一次性查找数据该函数的先前实现。

使用 InvalidFormulaException 中的其他详细信息更好地调试

为了向客户提供更多信息以解决电子表格中的错误,GcExcel 在 InvalidFormulaException 中添加了更多信息。异常现在将包括单元格的位置和公式文本以跟踪错误。因此,如果您遇到此异常,您将获得更多信息来解决电子表格中的问题。


服务端 Word 组件 GrapeCity Documents for Word 更新说明

GcWord 报告模板增强功能

模板标签的扩展语法检查

GcWord 现在包括模板处理时的模板标签语法检查。将扫描候选模板标签,并检查结构。如果发现任何错误,将引发异常,并提供有关问题的详细信息。

在下面的示例中,解析段落中指定的日期格式。格式中指定的字符被扫描并在异常中报告。

[code]
var coll = new[] { DateTime.Parse("2022/02/12"), DateTime.Parse("1011/03/04") };

var doc = new GcWordDocument();
doc.DataTemplate.DataSources.Add("ds", coll);
doc.Body.Paragraphs.Add(@"{{ds.value}:format(yyyy:MM:dd)}");         

doc.DataTemplate.Process();

//result
GrapeCity.Documents.Word.InvalidTemplateFormatException:
'Template key {{ds.value}:format(yyyy:MM:dd)} have non-escaped service char in the formatter param at position 23.
Chars '(',')',':','{','}' should be escaped.'
[/code]

添加特定于数据源的文化

使用 GcWord 模板,您现在可以将特定文化添加到添加到模板中的特定数据源。doc.DataTemplate.DataSources.Add(..) 方法中提供了新的区域性参数 。如果设置了此参数,则所有带有来自数据源的标签的文化特定转换都将使用提供的文化。

以下代码为不同的数据源添加了不同的文化:

支持 Decimal、DateTime 和 DateTimeOffset 作为原始类型

GcWord 模板 在模板中允许原始类型(如整数或浮点数)并使用“值”标签访问它们。 也可以通过这种方式使用Decimal、 DateTime和 DateTimeOffset类型 。 以下代码演示了对 DateTime 和 DateTimeOffset 类型的支持,同时添加到数据源以及使用 value 标记对其进行访问以设置 Date/DateTime 格式:

[code]
var doc = new GcWordDocument();
// The data source (Napoleon's first italian company battle dates from Wikipedia):
doc.DataTemplate.DataSources.Add("dsItalianBattles", new DateTime[]
{
     //first stage
     DateTime.Parse("1796/04/12"),
     DateTime.Parse("1796/04/14"),
     DateTime.Parse("1796/04/15"),
     DateTime.Parse("1796/04/19"),
     DateTime.Parse("1796/04/22"),

     //second stage
     DateTime.Parse("1796/05/10"),
     DateTime.Parse("1796/09/4"),
     DateTime.Parse("1796/10/15"),
     DateTime.Parse("1796/12/14"),
});

// The data source (world wide wars start dates):
doc.DataTemplate.DataSources.Add("dsWW", new DateTimeOffset[]
{               

     DateTimeOffset.Parse("28/07/1914"),
     DateTimeOffset.Parse("01/09/1939"),               

});

// Add a list template so that the data is formatted as a list:
var myListTemplate = doc.ListTemplates.Add(BuiltInListTemplateId.BulletDefault, "myListTemplate");

//DateTime list
doc.Body.Paragraphs.Add("Napoleon's first italian company battles dates:", doc.Styles[BuiltInStyleId.Heading1]);
// Add a list of battles dates:
var p = doc.Body.Paragraphs.Add("{{#dsItalianBattles}}{{dsItalianBattles.value}:format(yyyy-MM-dd)}{{/dsItalianBattles}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;

//DateTimeOffset list
doc.Body.Paragraphs.Add("World wars start dates:", doc.Styles[BuiltInStyleId.Heading1]);
p = doc.Body.Paragraphs.Add("{{#dsWW}}{{dsWW.value}:format(yyyy\\:MM\\:dd)}{{/dsWW}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
[/code]

对文本和形状应用阴影效果

您现在可以使用新的 API 在 MS Word 中自定义内容的外观,以便在形状和文本 Word .docx 文件中应用阴影效果。新的 Effects 属性被添加到 Font、Shape、Picture、GroupShape、CanvasShape、ShapeStyle 和 FormatSсheme 类中。阴影效果分为四类:

  • ShadowBase 是所有影子类的基础抽象类
  • ShadowPreset 和 InnerShadow 基于 ShadowBase 类
  • OuterShadow 基于 InnerShadow 类
  • TextEffects 类用于对 Font 类应用效果,仅包含 OuterShadow 阴影类型,而 ShapeEffects 是基于 TextEffects 类,并具有额外 的InnerShadow 和 ShadowPreset 阴影类型

以下快照显示了 应用于“Treadstone”文本 的外阴影效果和使用 GcWord API 应用于形状的 BuiltInShadowId.ProspectiveLowerLeft 枚举。

您可以将自定义阴影和内置阴影应用于文本和形状。请注意,目前 PDF/图像导出不支持阴影。

示例:将 markdown (.md) 文档导入 Word(并转换为 PDF/图像)

现在将您的 Markdown 文档导入 GcWord 并将它们转换为 .docx 文件。 GcWord 示例浏览器 现在实现了一个带有完整源代码的新示例,用于将 Markdown .md 文件转换为 .docx 文件和 PDF。转换由 GcWordWeb.Samples.MarkdownToWordRenderer.WordRenderer 类完成,使用 Markdig 包(BSD 2-Clause license)解析 .md 文件,并使用 GcWord OM 从中创建 MS Word 文档。WordRenderer C# 源代码包含在示例中。MarkdownToWordRenderer 源位于示例 zip 的 Samples/Markdown/Renderer 子目录中。

GcWordLayout

PdfOutputSettings 现在包括 PdfOutputSettings.SecurityHandler属性,可在将 Word .docx 文件转换为 PDF 导出时 访问其他与安全相关的功能(例如,密码、限制复制等)。看看下面的演示。


服务端 PDF 组件 GrapeCity Documents for PDF 更新说明

替换/删除 PDF 文档中的文本

您现在不仅可以使用常见的搜索选项(如整个单词、区分大小写和正则表达式(之前已支持))在 PDF 文档中搜索文本,还可以使用新的 API 替换或删除找到的文本实例 - ITextMap.ReplaceText(... ) 或 ITextMap.DeleteText(...) 方法。这在有多个 PDF 文档需要更新的情况下很有用。它提供了以编程方式更新和替换每个文件中某些信息的能力,从而为用户和程序员节省了时间和精力。

新方法也适用于 RTL 和垂直文本。替换文本时,新文本可以具有相同或不同(指定)的字体/字体大小。

删除文本可以在两个 DeleteTextMode 选项中完成。

标准:在这种模式下,文本在删除后的位置会移动。

PreserveSpace: 在该模式下,被删除文本的位置会保留一个空格,之后的文本不会移动。

以下代码使用标准 选项在 PDF 文档中查找文本“湿地”并删除文本:

[code]
// delete word "wetlands" from the document
using (FileStream fs = new FileStream(@"Wetlands.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{

    GcPdfDocument doc = new GcPdfDocument();
    doc.Load(fs);
    FindTextParams ftp = new FindTextParams("wetlands", true, false);
    doc.DeleteText(ftp, DeleteTextMode.Standard);
    doc.Save("wetlands_deleted_doc.pdf");

}
[/code]


关于葡萄城

葡萄城成立于 1980 年,是全球领先的软件开发技术和低代码平台提供商,以“赋能开发者”为使命,致力于通过各类软件开发工具和服务,创新开发模式,提升开发效率,推动软件产业发展,为“数字中国”建设提速。

产品与服务
活字格低代码平台
Wyn 商业智能软件
SpreadJS纯前端表格控件
技术服务体系
技术博客
低代码技术
客户与案例
典型客户
成功案例
用户访谈
合作与生态
合作伙伴网络
葡萄城市场
葡萄城与国产化
活字格用友客开工具
品牌活动
葡萄城公开课
品牌战略发布会
赋能开发者高峰论坛
企业级低代码发展研讨会
企业级低代码应用大赛
表格技术研讨会
了解葡萄城
葡萄城简介
愿景使命
研发与创新
荣誉奖项
加入我们
联系方式
联系我们
400-657-6008

葡萄城社区二维码

关注“葡萄城社区”

赋能开发者

西安葡萄城软件有限公司
全球领先的软件开发技术和低代码平台提供商

陕ICP备2020018819号  |   陕公网安备:61019002000258  |   隐私政策  |   网站地图  |  

国家   china
  • china   China
  • united_states   USA - International
  • japan   Japan
  • south-korea   South Korea

邮箱: info.xa@grapecity.com  |  Copyright © 2023 GrapeCity inc.