服务端表格组件 GrapeCity Documents for Excel 更新说明

支持SpreadJS的.sjs文件格式

在 GcExcel 的 V6.0 Update 2 版本中,增加了对 SpreadJS .sjs 文件格式的支持。通过导出为 .sjs 格式,可以实现更短的导出时间和更小的文件尺寸。现在,您可以将 xlsx、xlsm、csv、ssjson 等格式的文件导出为 .sjs 格式,以更高效地处理数据。

增强了Workbook类上的open和save方法,支持.sjs文件,当加载或保存.sjs文件时,可以通过OpenFileFormat和SaveFileFormat,来选择Sjs枚举项。

因为对.sjs文件格式的支持,则可以满足以下功能:

  • 快速将Excel文件转换为.sjs格式
  • 以更小的占用空间保存文件
  • 从.sjs文件中压缩的JSON文件生成单个JSON字符串
  • 使各种可用选项自定义SpreadJS.sjs文件的打开和保存

新添加两个类,SjsOpenOptions和SjsSaveOptions。在导入/导出.sjs文件时,可以通过这两个类来定制包含/排除特定的功能。

以下代码加载 SpreadJS 的 .sjs 文件,并通过使用 SjsOpenOptions 排除公式和样式,然后使用 GcExcel 打开并保存该文件。

    
// 创建一个新的工作簿
Workbook workbook = new Workbook();
InputStream stream = this.getResourceStream("sjs\\LoanDetails.sjs");

// .sjs 文件格式的 OpenOptions
SjsOpenOptions openOptions = new SjsOpenOptions();
openOptions.setIncludeFormulas(false);
openOptions.setIncludeStyles(false);

// GcExcel 支持使用 OpenOptions 打开 .sjs 文件格式
workbook.open(stream, openOptions);
    
// 保存为 .sjs 文件
workbook.save("OpenSjsWithOpenOptions.sjs");
    

形状文本的对齐选项

GcExcel在ITextRange接口中添加了新的TextAlignment属性,用于获取或设置形状中文本范围或段落的对齐方式。该属性可以给文本设置对齐方式,如左对齐、右对齐、居中、分散和两端对齐。在需要按照UI设计规则或按照数据格式对齐文本(例如将文本左对齐或将数字右对齐)的场景中非常有帮助。

以下代码将形状中多个段落的对齐方式设置为居中和左对齐:

    
IShape shape = worksheet.Shapes.AddShape(AutoShapeType.RoundedRectangle, (double)10, (double)10, (double)320, (double)150);
shape.TextFrame.TextRange.TextAlignment = TextAlignmentAnchor.Left;
shape.TextFrame.TextRange.Font.Name = "Calibri";
shape.TextFrame.TextRange.Font.Size = 16;
shape.TextFrame.TextRange.Font.Color.RGB = Color.Black;
shape.TextFrame.TextRange.Font.Underline = TextUnderlineType.None;

shape.TextFrame.TextRange.Paragraphs.Add("Quarterly Results");
shape.TextFrame.TextRange.Paragraphs[0].TextAlignment = TextAlignmentAnchor.Center;
shape.TextFrame.TextRange.Paragraphs[0].Font.Size = 28;
shape.TextFrame.TextRange.Paragraphs[0].Font.Underline = TextUnderlineType.Single;
shape.TextFrame.TextRange.Paragraphs.Add("");

shape.TextFrame.TextRange.Paragraphs.Add("Business Domain: E-Commerce");
shape.TextFrame.TextRange.Paragraphs[2].TextAlignment = TextAlignmentAnchor.Left;

shape.TextFrame.TextRange.Paragraphs.Add("Quarter: Q4");
shape.TextFrame.TextRange.Paragraphs[3].TextAlignment = TextAlignmentAnchor.Left;
    

在形状和图表中设置垂直文本方向

在某些文档中,希望将文本方向设置为垂直方向。GcExcel在形状和图表的API中添加了Direction属性:

  • IShape.TextFrame.Direction:用于形状的文本方向
  • ITickLabels.Direction:用于图表轴上刻度标签的文本方向
  • IChartTitle.Direction 或 IChartTitle.TextFrame.Direction:用于图表标题的文本方向
  • IAxisTitle.Direction 或 IAxisTitle.TextFrame.Direction:用于坐标轴标题的文本方向
  • IDataLabels.Direction:用于指定系列数据标签的文本方向
  • IDataLabel.Direction 或 IDataLabel.TextFrame.Direction:用于图表数据点上数据标签的文本方向

Direction属性接受TextDirection枚举选项,可设置文本在以下方向上的方向:

  • TextDirection.Horizontal:表示文本水平显示
  • TextDirection.Vertical:表示文本垂直显示
  • TextDirection.Rotate90:表示文本将旋转90度
  • TextDirection.Rotate270:表示文本将旋转270度
  • TextDirection.Stacked:表示文本将堆叠显示,读取顺序从左到右
  • TextDirection.StackedRtl:表示文本将堆叠显示,读取顺序从右到左

以下代码将文本的TextDirection设置为Stacked方向:

    
var shape = worksheet.Shapes.AddShape(AutoShapeType.Rectangle, worksheet.Range["C2:F12"]);
shape.TextFrame.TextRange.Add("欢迎来到葡萄城");

//将文本方向设置为堆叠,并且文本的阅读顺序从左到右。
shape.TextFrame.Direction = TextDirection.Stacked;
    

支持双面打印 仅适用于.NET版本

有时候我们需要在一页的两面打印一个包含长工作表的工作簿。GcExcel .NET提供了PrintOutOptions类中的Duplex枚举来启用/禁用页面上的双面打印。该枚举有四个选项,用户可以根据需要选择打印工作簿的方式:

  • Duplex.Default 表示打印机的默认双面打印设置
  • Duplex.Simplex 表示单面打印
  • Duplex.Vertical 表示双面垂直打印
  • Duplex.Horizontal 表示双面水平打印

以下代码将以双面垂直打印方式打印三份工作簿副本:


// 创建打印选项。
PrintOutOptions options = new PrintOutOptions();
// 设置打印的打印机名称为 "Printer"。
options.ActivePrinter = "Printer";
// 打印3份副本。
options.Copies = 3;
// 设置双面垂直打印。
options.Duplex = System.Drawing.Printing.Duplex.Vertical;
// 使用 "Printer" 打印此工作簿。
workbook.PrintOut(options);

 

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

对PDF打开和保存时的增强

在新的V6.0 Update 2版本中,GcPdf在处理由其他软件生成的现有PDF文档方面进行了改进,并提供了以下优势:

1、GcPdf现在可以加载和保存可能不严格符合PDF规范的PDF文档

2、GcPdf将保留嵌入在PDF文档中的任何非PDF规范的自定义数据

3、加载PDF文档的平均速度得到了改善

这些改进使得GcPdf能够更好地处理各种PDF文档,即使这些文档不是完全符合PDF规范或包含一些非标准的数据。同时,加载PDF文档的速度也得到了提升。

在不指定密码的情况下处理受密码保护的文件

GcPdf现在允许在不指定密码的情况下处理受密码保护的文件。在加载受密码保护的文件后,您现在可以执行以下操作而无需指定密码:

读取/写入不基于PDF字符串对象的属性,例如:

  • 您可以获取/设置CheckBoxField或RadioButtonField的值
  • 获取某个文档的特定统计信息,例如获取页面数、注释数等
  • 获取或更改文档元数据,因为元数据通常未加密
  • 更改某些类型字段的值:CheckBoxField、RadioButtonField;可以更改TextBoxField、CombTextField的值,但有一些限制

如果可以在不使用PDF字符串的情况下定义新对象,您可以添加新对象。例如,您可以向一个页面或所有页面添加一个SquareAnnotation。

新增了DecryptionOptions类来表示解密选项。当加载加密的PDF时,您可以将其作为(可选)参数传递给GcPdfDocument.Load()方法。通过将DecryptionOptions.ThrowExceptionIfInvalidPassword设置为false(默认为true),以允许加载受密码保护的PDF而无需指定其密码。另一个相关的标志是DecryptionOptions.ThrowExceptionIfUnsupportedSecurityOptions,默认情况下也为true。将其设置为false可以允许GcPdf加载具有未知或损坏的安全处理程序的文档。

以下代码示例展示了如何向受密码保护的PDF添加注释,而无需指定密码:

    
using var fs = File.OpenRead("financial-report.pdf");
var doc = new GcPdfDocument();
doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });
// 获取第一页的尺寸:
var page = doc.Pages[0];
var pageSize = page.Size;
// 添加一个方形注释:
SquareAnnotation sa = new SquareAnnotation();
sa.Page = page;
sa.Rect = new RectangleF(10, 10, pageSize.Width 20, pageSize.Height 20);
sa.Color = Color.Red;
doc.Save("AnnotationAdded.pdf");
    

操作底层PDF对象的API(GrapeCity.Documents.Pdf.Spec和GrapeCity.Documents.Pdf.Wrappers命名空间)

在这个版本中,GcPdf介绍了一个新的API,允许熟悉PDF规范的开发人员直接访问PDF底层对象,这些对象是构成PDF文档的基本组成部分。其中包括:

  • PDF数组,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfArray、PdfArrayObject、IPdfArray、IPdfArrayExt以及GrapeCity.Documents.Pdf.Wrappers命名空间的PdfArrayWrapper
  • PDF布尔值,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfBool、PdfBoolObject、IPdfBool和IPdfBoolExt
  • PDF字典,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfDict、PdfDictObject、IPdfDict、IPdfDictExt以及GrapeCity.Documents.Pdf.Wrappers命名空间的PdfDictWrapper
  • PDF名称,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfName、PdfNameObject、IPdfName和IPdfNameExt
  • PDF空值,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfNull、PdfNullObject、IPdfNull和IPdfNullExt
  • PDF数字,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfNumber、PdfNumberObject、IPdfNumber和IPdfNumberExt
  • PDF引用,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfRef、PdfRefObject、IPdfRef和IPdfRefExt
  • PDF流,参见GrapeCity.Documents.Pdf.Spec命名空间的PdfStreamObjectBase
  • PDF字符串,参见GrapeCity.Documents.Pdf.Spec命名空间的类型PdfString、PdfStringObject、IPdfString和IPdfStringExt

这些新的API可以用来访问PDF制作者有时会添加但在PDF规范中没有描述的自定义属性。例如,DocumentInfo对象是一个PDF字典。PDF规范列出了可能存在于该字典中的属性(Creator、Author等),但在许多实际的PDF文件中,DocumentInfo字典包含了PDF规范中不存在的“SourceModified”属性。GrapeCity.Documents.Pdf.Spec命名空间中的类型现在允许开发人员访问/编辑这样的自定义项。

请参阅GcPdf参考文档以获取有关GrapeCity.Documents.Pdf.Spec和GrapeCity.Documents.Pdf.Wrappers命名空间的更多信息。

示例:获取图像属性

使用上述新的API,现在可以使用从流中检索的图像处理由图像扫描仪创建的许多PDF(其中大多数每页只包含一个JPEG或G4 TIFF图像)。 GcPdf包括新的PdfImageInfo类,它是PdfDictWrapper对象的派生类。该类包含许多方法,允许获取底层PDF流对象的属性/数据。此添加将检索流图像并直接解压缩或处理图像。

您可以检索以下图像属性:

  • 直接检索每个页面上每个图像的流(使用GetImages()检索)
  • 检索上述图像流的压缩格式(Filter)
  • 检索上述图像流的黑白信息(Decode或BlackIs1)
  • 检索可识别上述图像流颜色的信息(ColorSpace或BitsPerComponent)
  • 检索每个掩码的流和每个信息(ImageMask)
  • 等等……

以下代码从PDF流中检索图像属性:

    
using (FileStream fs = new FileStream(@"..\..\..\06-1.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
      GcPdfDocument doc = new GcPdfDocument();
      doc.Load(fs);
      var imgs = doc.GetImages();
      // 获取PDF中第一张图像的信息(我们知道有一张图像,因此为简单起见,没有进行索引检查):
                
      PdfImage pi = (PdfImage) imgs[0].Image; // 注意:这里不需要强制类型转换,PdfImageBase是Image属性的类型。
      Console.WriteLine($"PdfImage object ID: {pi.ObjID}");
      // PdfImage是PdfDictWrapper对象的派生类,它有许多方法可用于获取底层PDF流对象的属性/数据
      using (PdfStreamInfo psi = pi.GetPdfStreamInfo())
      {
            Console.WriteLine($"    Image stream length: {psi.Stream.Length}");
            Console.WriteLine($"        ImageFilterName: {psi.ImageFilterName}");
            Console.WriteLine($"ImageFilterDecodeParams: {psi.ImageFilterDecodeParams}");
            // 打印ImageFilterDecodeParams的内容
            foreach (var kvp in psi.ImageFilterDecodeParams.Dict)
            {
                 Console.WriteLine($"{kvp.Key}: {kvp.Value}");
            }
            // 示例如何获取BlackIs1的值:
            var blackIs1 = psi.ImageFilterDecodeParams.GetBool(PdfName.Std.BlackIs1, null);
            Console.WriteLine($"BlackIs1: {blackIs1}");
       }
      // 打印PdfImage字典的属性
      Console.WriteLine();
      Console.WriteLine("Properties of PdfImage dictionary:");
      foreach (KeyValuePair kvp in pi.PdfDict.Dict)
      {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
      } 
      var cs = pi.Get(PdfName.Std.ColorSpace);
      Console.WriteLine($"ColorSpace: {cs.GetType().Name} {cs}");
      var bpc = pi.Get(PdfName.Std.BitsPerComponent);
      Console.WriteLine($"BitsPerComponent: {bpc?.GetType().Name} {bpc}");
}
    

输出显示了获取的所有图像属性。

在TextField中设置格式

GcPdf现在允许用户使用直接的方法(SetPercentFormat、SetNumberFormat、SetDateFormat、SetTimeFormat、SetSpecialFormat方法)以直观的方式给TextField指定日期、时间、数字格式和特殊格式。这些方法已经添加到TextField、CombTextField和ComboBoxField类中。新的方法支持设置与Acrobat中的TextField属性类似的属性。

新增了枚举SpecialFormat、CurrencySymbolStyle、NumberNegativeStyle和NumberSeparatorStyle。这些枚举用作上述方法的参数。

以下代码使用新的方法和参数在TextField上设置数字值。

    
GcPdfDocument doc = new GcPdfDocument();
var p = doc.NewPage();
var g = p.Graphics;
TextField result = new TextField();
result.Widget.Page = p;
result.Widget.Rect = new System.Drawing.RectangleF(100,100,100,100);
result.Widget.Border.Width = 1;
result.SetNumberFormat(2, Field.NumberSeparatorStyle.Dot, Field.NumberNegativeStyle.ShowParentheses, "\u20ac", Field.CurrencySymbolStyle.BeforeNoSpace);
result.Value = "12345.67f";
result.SetNumberValue(12345.67f, 2, Field.NumberSeparatorStyle.Dot, Field.NumberNegativeStyle.None, "$", Field.CurrencySymbolStyle.BeforeNoSpace);
p.Doc.AcroForm.Fields.Add(result);
doc.Save("NumberTextField.pdf");        
    

为GcGraphics绘制布局的辅助类

在最新版本的GcPdf中,添加了新的布局引擎,引入了GrapeCity.Documents.Layout命名空间中的LayoutRect和其他相关类,以基于约束和扁平元素层次结构的布局模型来实现在PDF页面或图像上绘制多个元素而无需计算每个元素相对于其他元素的位置。新的布局引擎提供了灵活性,可以定位和调整元素的大小,从而实现在PDF和图像上绘制复杂的图形布局。

在V6.0 Update 2版本中,GcPdf还在GrapeCity.Documents.Layout.Composition命名空间中添加了额外的类:Surface、Layer、View、Space和Visual类,它们充当布局引擎与绘图表面之间的媒介,使得绘制更复杂的图形、文本和图像更加容易。下面简要介绍这些类的功能:

  • Surface是Composition引擎中的主要类。它包含一个LayoutHost(布局引擎的根对象)和一个或多个视图(层)。层由可绘制元素(visuals)和嵌套层组成。Surface类的Render方法调用LayoutHost类的PerformLayout方法来计算表面布局,然后它会在指定的GcGraphics对象上从底部到顶部绘制所有层,包括嵌套层
  • 层分为两种类型:Layer类对象和View类对象(派生自Layer对象)。View对象封装了LayoutView对象,它代表具有自己的转换矩阵的单独坐标系统。Layer对象充当轻量级的视图,具有自己的可绘制元素列表、嵌套层和可能的裁剪区域
  • 层包含可绘制元素(Visuals)和空间(Spaces)。空间对象表示可能影响其他元素布局但本身不会被绘制的LayoutRect。Visual类继承自Space类。Visual类表示将在目标GcGraphics上绘制的元素

此外,这些类还允许您自定义绘制图形的Z顺序和裁剪。例如,可以从多个可绘制元素组合成一个PDF页面,然后在渲染到文档之前进一步调整这些元素。某些可视元素或层可以隐藏,其他可视元素可以在Z顺序中移动等。

还引入了其他API来实现各种布局。如需了解有关新类和每个类的功能的更多信息,请参阅相关文档。

以下是使用这些API可以实现的一个非常复杂布局的示例:

请查看用于生成此布局的完整源代码的在线演示:Documents for PDF | Text Flow (C#)

 

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

对于Office Math函数和转换为MathML的支持

GcWord现在支持在Word文档中创建和编辑Office Math内容。GcWord中的OMath支持包括完整的API,用于处理在科学、数学和通用目的的Word文档中广泛使用的数学符号、公式和方程。以下是OMath支持引入的新API的主要亮点:

  • 用于表示GcWord中的Office Math内容的两个主要类是OMathParagraph和OMath。OMathParagraph表示带有Office Math内容的段落,而OMath表示内联的Office Math区域,可以包含在OMathParagraph或常规段落中
  • 提供了专门的类(如OMathFunction、OMathEquationArray、OMathRadical等),用于表示OMath区域中的各种数学结构。这些类都是从通用的抽象OMathStruct基类派生而来
  • 可以通过新的RangeBase属性(OMathParagraphs、OMaths、OMathStructs、OMathElements和OMathMatrixRows)访问Office Math内容
  • 为了方便添加MS Word支持的内置方程,RangeBase、OMathParagraph、OMath和OMathElement类上提供了方便的Add/Insert方法,接受一个OMathBuiltInEquation枚举值,用于识别所需的方程
  • 包含一个实用的MathMLConverter类,可以方便地在GcWord的OMath内容和MathML之间进行转换

有关GcWord中OMath支持的详细信息,请参阅Office Math文档。

以下代码使用OMath类和其函数将一个方程添加到Word文件中:

    
var sampleDoc = new GcWordDocument();
var om = sampleDoc.Body.AddParagraph().AddOMathParagraph().AddOMath();
om.AddRun("Γ").Font.Italic = false;
om.AddDelimiter(new string[] { "z" });
om.AddRun("=");
var nary = om.AddNary("", "0", "∞", "∫");
nary.Base.AddSuperscript("t", "z-1");
nary.Base.AddSuperscript("e", "-t");
nary.Base.AddRun("dt");
om.AddRun("=");
var frac = om.AddFraction();
var superscript = frac.Numerator.AddSuperscript("e", "-");
superscript.Superscript.AddRun("γ").Font.Bidi = true;
superscript.Superscript.AddRun("z");
frac.Denominator.AddRun("z");
nary = om.AddNary("", "k=1", "∞", "∏");
superscript = nary.Base.AddSuperscript("", "-1");
var delimiter = superscript.Base.AddDelimiter();
var item = delimiter.Items.Add();
item.AddRun("1+");
item.AddFraction("z", "k", null);
superscript = nary.Base.AddSuperscript("e", "z");
superscript.Superscript.AddRun("/").OMathFormat.IsLiteral = true;
superscript.Superscript.AddRun("k");
om.AddRun(",  γ≈0.577216");
sampleDoc.Save("MathEquation.docx");        
    

新增方法用于向 Word 文档添加内容

到目前为止,在Word文档中添加内容对象有一种或多种方式。例如-可以通过段落创建构造函数调用-doc.Body.Paragraphs.Add(“text”)或使用paragraph.GetRange()。Runs.Add(...)并在此调用之前创建段落来添加段落的“runs”。然而,使用V6.0 Update 2版本,现在可以直接在段落元素上使用新的'AddRun(...)'方法来创建runs。

类似地,GcWord在Word文档中的每种内容对象上添加了"Add<content object>(..)"方法,这样它们就可以直接添加到其父对象中,使代码更简洁高效。现在,可以使用新的辅助方法将这些对象直接添加到Word文档中的不同节或内容对象中:

  • 表格(Table)
  • 段落(Paragraph)
  • 内容控件(ContentControl)
  • 简单域(SimpleField)
  • 超链接(Hyperlink)
  • 双向覆盖(BidirectionalOverride)
  • 数学公式段落(OMathParagraph)
  • 数学公式(OMath)
  • 运行内容(Run)
  • 脚注(Footnote)
  • 尾注(EndNote)
  • 复杂域(ComplexField)
  • 组合形状(GroupShape)
  • 形状(Shape)
  • 图片(Picture)
  • 手写形状(InkShape)

请查看以下代码,该代码使用新方法'AddRun(..)'将一个段落运行添加到一个段落中:


GcWordDocument doc = new GcWordDocument();
            
// 添加一个带有默认格式的段落
var p = doc.Body.AddParagraph("text1");
            
// 在该段落中添加另一段使用“Heading1”样式格式化的文本
// 先前的代码应该是:p.GetRange().Runs.Add("text2", doc.Styles[BuiltInStyleId.Heading1]);
// 现在的代码更简洁,更清晰地表明可以将内容添加到对象中
 p.AddRun("text2", doc.Styles[BuiltInStyleId.Heading1]);
    

在GcWord模板中转义模板标签

如果你想要防止特定的数据模板标签被数据模板引擎处理(即在模板扩展后字面上引用它),请在标签的开头双花括号之前插入一个反斜杠。

以下代码片段展示了如何转义原本会打印数据值的标签:


var dsPoint = new string[] { "2.2", "3.3", "4.4" };
var doc = new GcWordDocument();
doc.Body.Paragraphs.Add(@"\{{dsPoint.value}:todouble():format(0.#%)}");
doc.DataTemplate.DataSources.Add("dsPoint", dsPoint);
doc.DataTemplate.Process(CultureInfo.GetCultureInfo("en-US"));
doc.Save("DocumentWithSingleSlash.docx"); 
    

另外,为了在模板标签之前使用反斜杠而不禁用模板处理,GcWord允许您插入两个或更多反斜杠,取决于需要多少个反斜杠。在处理模板标签时,它会从前面的反斜杠中移除一个反斜杠。

下面的代码向模板语法添加了双斜杠。当处理模板语法时,这将在生成的Word文件中添加一个反斜杠。

    
var dsPoint = new string[] { "2.2", "3.3", "4.4" };
var doc = new GcWordDocument();
doc.Body.Paragraphs.Add(@"\\{{dsPoint.value}:todouble():format(0.#%)}");
doc.DataTemplate.DataSources.Add("dsPoint", dsPoint);
doc.DataTemplate.Process(CultureInfo.GetCultureInfo("en-US"));
doc.Save("DocumentWithDoubleSlash.docx");        
    

历史版本

查看更多关于 GC Documents 服务端表格组件的历史版本。