We are pleased to announce the GrapeCity Documents v6.2 release! The latest version of GcDocs adds styles support to SpreadJS .sjs file format in GcExcel .NET, support for SpreadJS .sjs in GcExcel Java, optimized loading and saving of PDF files in GcPdf, new paint and text tools in GcImageViewer, support for OMath in GcWord, enhancements in GcPdfViewer and many more additions to the Document APIs.
Learn more about the great new features below!
Ready to Check Out the Latest? Download GrapeCity Documents now!
With the new v6.2 release, GcPdf enhances the loading and saving of PDF documents and provides the following advantages:
Due to changes in how GcPdf works with loaded PDFs, some of the lower-level GcPdf APIs had to be changed, which may require minor changes in your code if it uses those APIs; complete list of the affected APIs.
GcPdf now allows working with password-protected files without specifying the password. After loading a password-protected file, you can now perform the following without specifying the password:
A new DecryptionOptions class has been introduced that represents the decryption options. You can pass it as an (optional) argument to the GcPdfDocument.Load() method when loading an encrypted PDF. In particular, you can set the DecryptionOptions.ThrowExceptionIfInvalidPassword flag to false (it is true by default) to allow loading password-protected PDFs without specifying their passwords. Another related flag is DecryptionOptions.ThrowExceptionIfUnsupportedSecurityOptions. It is also true by default. Setting it to false will enable GcPdf to load documents with unknown or broken security handlers.
The following code adds an annotation to a password-protected PDF without specifying the password:
using var fs = File.OpenRead("financial-report.pdf");
var doc = new GcPdfDocument();
doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });
// Get the size of the first page:
var page = doc.Pages[0];
var pageSize = page.Size;
// Add a square annotation:
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");
In this release, GcPdf introduces a new API that allows developers familiar with the PDF specification to directly access the primitive PDF objects, which are the building blocks of any PDF document. These include:
These new APIs can be used, for instance, to access custom properties that are sometimes added by PDF producers but are not described in the PDF spec. For example, the DocumentInfo object is a PDF dictionary. The PDF specification lists the properties which can be present in this dictionary (Creator, Author, etc.). Still, in many real-life PDF files, the DocumentInfo dictionary includes a "SourceModified" property which is absent in the PDF spec. The types from the GrapeCity.Documents.Pdf.Spec namespace now allow developers to access/edit such custom items.
Please see the GcPdf reference for more information on the GrapeCity.Documents.Pdf.Spec and GrapeCity.Documents.Pdf.Wrappers namespaces.
Using the new API above, many PDFs created by image scanners (most of which consist of only one JPEG or G4 TIFF image per page) can now be processed with the images retrieved from the stream. GcPdf includes the new PdfImageInfo class, a descendant of the new PdfDictWrapper object. The class consists of a lot of methods that allow to get properties/data of underlying PDF stream objects. This addition would retrieve stream images and directly decompress or process images.
You can retrieve the following image properties:
The following code retrieves image properties from a PDF stream:
using (FileStream fs = new FileStream(@"..\..\..\06-1.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
GcPdfDocument doc = new GcPdfDocument();
doc.Load(fs);
GcPdfDocument doc = new GcPdfDocument();
doc.Load(fs);
var imgs = doc.GetImages();
// Get the info about the first image in the PDF
// (we know there is one image, so no index checks for example's simplicity sake):
PdfImage pi = (PdfImage) imgs[0].Image; // NOTE: no cast here, PdfImageBase is the type of the Image property.
Console.WriteLine($"PdfImage object ID: {pi.ObjID}");
// The PdfImage is a descendant of PdfDictWrapper object it has a lot of methods
// which allow to get properties/data of underlying PDF stream object
using (PdfStreamInfo psi = pi.GetPdfStreamInfo())
{
Console.WriteLine($" Image stream length: {psi.Stream.Length}");
Console.WriteLine($" ImageFilterName: {psi.ImageFilterName}");
Console.WriteLine($"ImageFilterDecodeParams: {psi.ImageFilterDecodeParams}");
// dump content of ImageFilterDecodeParams
foreach (var kvp in psi.ImageFilterDecodeParams.Dict)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// example how to get value of BlackIs1:
var blackIs1 = psi.ImageFilterDecodeParams.GetBool(PdfName.Std.BlackIs1, null);
Console.WriteLine($"BlackIs1: {blackIs1}");
}
// dump properties of PdfImage dictionary
Console.WriteLine();
Console.WriteLine("Properties of PdfImage dictionary:");
foreach (KeyValuePair<PdfName, IPdfObject> kvp in pi.PdfDict.Dict)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
var cs = pi.Get<IPdfObject>(PdfName.Std.ColorSpace);
Console.WriteLine($"ColorSpace: {cs.GetType().Name} {cs}");
var bpc = pi.Get<IPdfObject>(PdfName.Std.BitsPerComponent);
Console.WriteLine($"BitsPerComponent: {bpc?.GetType().Name} {bpc}");
}
The output displays all Image properties retrieved.
GcPdf now allows users to specify the date, time, number formats, and special formats to TextField in an intuitive way using new direct methods SetPercentFormat, SetNumberFormat, SetDateFormat, SetTimeFormat, SetSpecialFormat methods added to TextField, CombTextField, ComboBoxField classes. The new methods would support setting properties similar to the TextField properties in Acrobat.
New enums SpecialFormat, CurrencySymbolStyle, NumberNegativeStyle, and NumberSeparatorStyle have been added. These are used as parameters in the methods above.
The following code sets the number value on TextField using the new method and parameters:
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");
GcPdfViewer now supports enhancing the Document List panel using custom HTML markup. GcPdfViewer provides name, path, title, and previewContent properties in DocumentListItem type, allowing the user to specify custom HTML markup to represent the documents' list. The following is a brief description of the properties:
The existing client-side properties and methods - documentListUrl option and addDocumentListPanel and loadDocumentList methods have been enhanced to accept DocumentListItem as a parameter to specify a predefined list of document list items.
The following code sets properties to the first tile, ‘Finance’, in the Document list panel:
const options = {
workerSrc: "/documents-api-pdfviewer/demos/product-bundles/build/gcpdfviewer.worker.js",
supportApi: {
apiUrl: window.top.SUPPORTAPI_URL,
token: window.top.SUPPORTAPI_TOKEN,
webSocketUrl: false
},
restoreViewStateOnLoad: false
};
const baseAssetsPath = "/documents-api-pdfviewer/demos/product-bundles/assets/";
options.documentListUrl = [
{
path: baseAssetsPath + "pdf/documents-list/financial-report.pdf",
title: "Finance",
previewContent: renderPreviewCard("Finance",
"View Financial, budget reports and collaborate over them.",
baseAssetsPath + "images/preview/svg/Finance.svg")
},
];
For the complete code, please have a look at this demo.
GcPdfViewer supports several keyboard shortcuts that can make working with PDF documents in the viewer more efficient. GcPdfViewer also supports redefining, disabling, overriding, and removing the default keyboard shortcuts, as well as binding the default keyboard shortcuts to other keys and creating custom keyboard shortcuts via API using the shortcuts option of the ViewerOptions class.
GcPdfViewer also supports redefining, disabling, overriding, and removing the default keyboard shortcuts, as well as binding the default keyboard shortcuts to other keys and creating custom keyboard shortcuts via API using the shortcuts option of the ViewerOptions class.
The following code helps to bind the holdToPan action to the 'P' key:
// Bind the "P" shortcut to the holdToPan action and leave the Ctrl+P shortcut for the "print" action.
viewer.options.shortcuts["P"] = [{ ctrl: true, tool: "print" }, { tool: "holdToPan" }];
Look at the full list of keyboard shortcuts supported in the Help link below.
This new release includes updates to the existing GcExcel .NET Excel and Java library and API tools and additions to our Javascript-based GrapeCity Documents Data Viewer. Have a look at the details of the release below:
View the full blog for release details.
GcWord now supports creating and editing Office Math content in Word documents. The OMath support in GcWord includes complete API to work with mathematical symbols, formulas, and equations widely used in scientific, mathematical, and general-purpose Word documents. Following are key highlights of the new API introduced with OMath support -
For the full details on OMath support in GcWord, please see the docs.
The following code adds an equation to a Word file with OMath class and its functions:
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; //w:cs was used
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; //m:lit used.
superscript.Superscript.AddRun("k");
om.AddRun(", γ≈0.577216");
sampleDoc.Save("MathEquation.docx");
Till now, it was possible to add content objects in Word documents in one or more ways. For example, it was possible to add ‘runs’ of a paragraph either by paragraph creation constructor call - doc.Body.Paragraphs.Add(“text“) or using a paragraph.GetRange().Runs.Add(…) and create a paragraph before this call. However, with the v6.2 release, creating runs directly on paragraph elements will now be possible using the new ‘AddRun(..)’ method.
Similarly, GcWord adds ‘Add<content object>(..)’ methods to each kind of content in Word documents so that they can be directly added to their parent object, making the code shorter and more efficient. Each of these objects can now be directly added to different sections or content objects in Word documents using new Helper methods:
Have a look at the following code that adds a paragraph run to a paragraph with the new method ‘AddRun(..)’:
GcWordDocument doc = new GcWordDocument();
// add paragraph with default formatted text
var p = doc.Body.AddParagraph("text1");
// add another text into the paragraph formatted with "Heading1" style
// previously code should look like: p.GetRange().Runs.Add("text2", doc.Styles[BuiltInStyleId.Heading1]);
// now the code is shorter and more clear what content can be added into the object
p.AddRun("text2", doc.Styles[BuiltInStyleId.Heading1]);
Look at the following resources to see a complete list of newly supported helper methods.
Help | Demo - Built-in Table Styles | Demo - Nested Table Helpers | Demo - Hyperlink Fields Helpers | Demo - Content Controls Helpers
If you want to prevent a particular data template tag from being processed by the data template engine (i.e., quote it literally in your document after template expansion), insert a backslash before the tag’s opening double curly brace.
The following code snippet shows how to escape tags that would otherwise print the data values:
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");
Additionally, to use backslashes before a template tag without disabling the template processing, GcWord allows you to insert two or more backslashes, depending on how many are needed. It will remove one backslash from prepending backslashes when processing template tags.
The following code adds a double-slash to the template syntax. This would add a single backslash in the resultant Word file when the template syntax is processed:
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");
Now draw freehand content or add text effortlessly over images to add additional information to your images. GcImageViewer adds new Paint and Text tools to draw or add text over images. The tools have been added to the second toolbar of the viewer.
Have a look at the details below.
Paint options
Settings
Other options
The text tools toolbar contains the “Text” tool and related settings such as Font Size, Font Name, Text Color, and Bold and Italic font styles.
You can also perform the following operations with the text tools:
Help Paint Tools | Help Text Tools | Demo Paint Tools | Demo Text Tools
Image filters can help you enhance your photos. Whether you need marketing images for your business, analyze image details, or enhance images, various image filters are supported in GcPdfViewer. In the v6.2 release, GcPdfViewer adds two new widely used filters - Vibrance and Saturation. The two filters are added to the Image Filters panel, along with other filters. Also added is the ability to set the ‘Intensity’ of the filter by adjusting the slider, the ‘Preview’ button to preview the image filter temporarily, and the ‘Apply/Cancel' buttons to apply or cancel applying the image filter.
In the last release, GcPdf, GcImaging added a new layout engine, introducing LayoutRect and other related classes in the GrapeCity.Documents.Layout namespace to implement a layout model based on constraints and a flat hierarchy of elements where multiple elements are drawn on a PDF page or images without calculating the positions of each element relative to the other. The new layout engine thereby adds flexibility to position and size the elements enabling the drawing of complex graphic layouts on PDFs and images.
In the v6.2 release, GcPdf, and GcImaging add additional classes - Surface, Layer, View, Space, and Visual classes in GrapeCity.Documents.Layout.Composition namespace is a medium between the layout engine and the drawing surface, making drawing even more complex graphics, text, and images easier. Here is a brief about the functions of these classes:
Furthermore, these classes enable you to customize the z-order and clipping of the drawn graphics. For example, it is possible to compose a PDF page from a number of visuals, then further adjust those visuals before rendering to the document. Some visuals or layers can be hidden. Others moved in z-order, and so on.
Additional API is also introduced to achieve various layouts. To read about the new classes and functions of each, refer to the documentation.
To learn more about the typical steps to create a layout, refer to this content: Documents for Imaging | Composition
Here is an example of a complex layout that can be achieved using these APIs.
See this online demo for the complete source code that is used to produce this layout: Documents for PDF | Text Flow (C#)
What do you think of the new release? Drop your comments below.
Ready to Check Out the Latest? Download GrapeCity Documents now!