# Aspose.3D FOSS for Java URL: https://blog.aspose.org/3d/java/ --- Product: Aspose.3D Platform: java Page Type: index Canonical URL: https://blog.aspose.org/3d/java/ --- # Aspose.3D FOSS for Java ## Related Topics - [Introducing Aspose.3D FOSS for Java](https://blog.aspose.org/3d/java/3d-java-obj-stl-gltf-library/) - [Key Features of Aspose.3D FOSS for Java](https://blog.aspose.org/3d/java/3d-java-scene-graph-materials/) - [3D Scene Management in Java with Aspose.3D FOSS](https://blog.aspose.org/3d/java/3d-scene-management-java/) - [Working with 3D File Formats in Java Using Aspose.3D FOSS](https://blog.aspose.org/3d/java/convert-obj-stl-gltf-java/) --- # Introducing Aspose.3D FOSS for Java URL: https://blog.aspose.org/3d/java/3d-java-obj-stl-gltf-library/ Aspose.3D FOSS for Java is an open-source, MIT-licensed library for loading, manipulating, and saving 3D file formats including OBJ, STL, glTF, and FBX. --- Product: Aspose.3D Platform: java Page Type: index Canonical URL: https://blog.aspose.org/3d/java/3d-java-obj-stl-gltf-library/ --- # Introducing Aspose.3D FOSS for Java We are excited to announce the availability of **Aspose.3D FOSS for Java** -- a free, open-source library for working with 3D file formats in Java applications. Built as a pure Java solution with no native dependencies, the library runs on Java 21 and later, making it accessible to a broad range of projects and environments. This post walks through what the library offers, how to get started, and where to go from here. ## What Is Aspose.3D FOSS for Java? Aspose.3D FOSS for Java is a lightweight 3D file processing library published under the **MIT license**. It provides a scene-graph API that lets you load, inspect, transform, and save 3D models across several widely used formats. The library is entirely written in Java and requires no external native binaries or platform-specific configurations. The source code is available on GitHub: **[https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java)** ### Key Highlights - **Pure Java** -- no JNI, no native libraries, no platform restrictions. - **Java 21+** compatible. - **MIT licensed** -- use it in personal, commercial, or proprietary projects without restrictions. - **Scene-graph architecture** -- a familiar tree of nodes, meshes, cameras, and materials. - **Multi-format support** -- read and write OBJ, STL, glTF 2.0, and GLB files; read FBX files. ## Quick Start ### Maven Installation Add the following dependency to your `pom.xml`: ### Your First Conversion The simplest use case is loading a 3D file in one format and saving it in another. Here is a two-line conversion from OBJ to STL: ```java import com.aspose.threed.*; public class QuickConvert { public static void main(String[] args) throws Exception { Scene scene = Scene.fromFile("cube.obj"); scene.save("output.stl"); } } ``` The `Scene` class is the central entry point. Call `Scene.fromFile` with a file path to load a model, then call `save()` with the target path. The library infers the format from the file extension. ### Building a Scene from Scratch You can also construct scenes programmatically: ```java import com.aspose.threed.*; public class BuildScene { public static void main(String[] args) throws Exception { Scene scene = new Scene(); Node node = scene.getRootNode().createChildNode("Box"); Transform t = node.getTransform(); t.setTranslation(1, 2, 3); scene.save("scene.gltf"); } } ``` This creates a new scene, adds a child node named "Box" under the root, positions it at coordinates (1, 2, 3), and exports the result as a glTF file. ### Loading with Format-Specific Options When you need finer control over the loading process, each format provides a dedicated options class. For example, loading an STL file with explicit options: ```java import com.aspose.threed.*; public class LoadWithOptions { public static void main(String[] args) throws Exception { StlLoadOptions opts = new StlLoadOptions(); Scene scene = Scene.fromFile("part.stl", opts); // Inspect the loaded scene System.out.println("Root children: " + scene.getRootNode().getChildNodes().size()); // Re-export as OBJ scene.save("part.obj"); } } ``` The `Scene.fromFile` static method accepts any of the load option types: `ObjLoadOptions`, `StlLoadOptions`, `GltfLoadOptions`, or `FbxLoadOptions`. ### Traversing the Scene Graph Once a scene is loaded, you can walk the node tree to inspect or modify its contents: ```java import com.aspose.threed.*; public class TraverseScene { public static void main(String[] args) throws Exception { Scene scene = Scene.fromFile("model.gltf"); for (Node child : scene.getRootNode().getChildNodes()) { System.out.println("Node: " + child.getName()); Transform t = child.getTransform(); System.out.println(" Translation: " + t.getTranslation()); Entity entity = child.getEntity(); if (entity instanceof Mesh) { Mesh mesh = (Mesh) entity; System.out.println(" Vertices: " + mesh.getControlPoints().size()); } } } } ``` This pattern is useful for debugging, generating reports about model contents, or selectively modifying parts of a scene before re-exporting. ### Applying Transforms Positioning nodes in 3D space is done through the `Transform` object on each `Node`: ```java import com.aspose.threed.*; public class TransformExample { public static void main(String[] args) throws Exception { Scene scene = new Scene(); Node parent = scene.getRootNode().createChildNode("Parent"); parent.getTransform().setTranslation(10, 0, 0); Node child = parent.createChildNode("Child"); child.getTransform().setTranslation(5, 0, 0); child.getTransform().setScale(2, 2, 2); // Child's world position is (15, 0, 0) due to // parent-child transform inheritance scene.save("transformed.gltf"); } } ``` Transforms follow the standard parent-child inheritance model: a child's world-space position is the combination of its local transform and all ancestor transforms up to the root. ## What's Included The library ships with a focused set of capabilities designed around the 3D scene-graph model. ### Scene Graph The scene graph is the backbone of the API. Every 3D file is represented as a tree structure: | Class | Role | |---|---| | `Scene` | Top-level container; the root of the scene graph | | `Node` | A named position in the tree; holds transforms and child nodes | | `Entity` | Abstract base for visual objects attached to nodes | | `Mesh` | Polygonal geometry -- vertices, faces, normals | | `Camera` | Virtual camera definition | | `Transform` | Local translation, rotation, and scale for a node | | `GlobalTransform` | Computed world-space transform | ### Materials The library provides a PBR (Physically Based Rendering) material model: - **PbrMaterial** -- physically based rendering material with albedo, metalness, roughness, emissive color, and transparency. This is the only concrete material class available in the Java edition. ### Math Utilities The `com.aspose.threed` package includes essential math primitives: - **Vector3** -- 3-component vector for positions, directions, and colors. - **Matrix4** -- 4x4 transformation matrix. - **Quaternion** -- rotation representation. - **BoundingBox** -- axis-aligned bounding box for spatial queries. ```java Vector3 a = new Vector3(1, 0, 0); Vector3 b = new Vector3(0, 1, 0); Vector3 c = Vector3.add(a, b); // (1, 1, 0) ``` ### Load and Save Options Each format has dedicated option classes that let you control import and export behavior: | Format | Load Options | Save Options | |---|---|---| | OBJ | `ObjLoadOptions` | `ObjSaveOptions` | | STL | `StlLoadOptions` | `StlSaveOptions` | | glTF / GLB | `GltfLoadOptions` | `GltfSaveOptions` | | FBX | `FbxLoadOptions` | -- (import only) | For example, to export glTF with pretty-printed JSON: ```java GltfSaveOptions opts = new GltfSaveOptions(); opts.setPrettyPrint(true); scene.save("output.gltf", opts); ``` ## Supported Formats The following table summarizes the formats that Aspose.3D FOSS for Java can read and write. | Format | Extension | Import | Export | Notes | |---|---|---|---|---| | OBJ | `.obj` | Yes | Yes | With MTL materials | | STL | `.stl` | Yes | Yes | Binary + ASCII | | glTF 2.0 | `.gltf` | Yes | Yes | JSON format | | GLB | `.glb` | Yes | Yes | Binary glTF via GltfSaveOptions | | FBX | `.fbx` | Yes | No | Import only | OBJ, STL, glTF, and GLB support both loading and saving. FBX is supported for import only. ### Format Selection Guide Choosing the right format depends on your use case: - **OBJ** is ideal when you need maximum compatibility across 3D tools. Nearly every modeling application can read and write OBJ. It works well for mesh data exchange but carries only basic material information through companion MTL files. - **STL** is the format of choice for 3D printing workflows. It stores raw triangulated geometry without materials or scene hierarchy, which is exactly what slicer software expects. If your pipeline ends at a 3D printer, STL is the straightforward choice. - **glTF** is the modern standard for web and real-time 3D. It supports PBR materials, full scene hierarchies, and is designed for efficient transmission. Use glTF when building web-based viewers, working with three.js or Babylon.js, or targeting any real-time rendering pipeline. - **FBX** is deeply integrated into game development and digital content creation workflows. It supports rich scene data including hierarchies and materials. Aspose.3D FOSS for Java supports FBX **import only** -- use it to load FBX assets and convert them to other formats. ### Known Limitations It is important to note that `Scene.render` is **not supported** in the FOSS edition. Calling this method will throw an `UnsupportedOperationException`. The library is designed for file-based 3D processing -- loading, manipulating, transforming, and saving models -- rather than real-time rendering to a display. ## Open Source and Licensing Aspose.3D FOSS for Java is released under the **MIT License**. This means you are free to: - Use the library in commercial and proprietary applications. - Modify the source code to fit your needs. - Distribute the library as part of your own software. There are no royalty fees, no usage limits, and no attribution requirements beyond what the MIT license specifies. The full source code is hosted on GitHub, and contributions are welcome: **[https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java)** ## System Requirements | Requirement | Detail | |---|---| | Java version | 21 or later | | Dependencies | None (pure Java) | | Platforms | Any platform that runs a JVM | | Build tool | Maven (recommended) | ## Getting Started Here are the resources to help you get up and running: - **Documentation** -- comprehensive guides and API walkthroughs are available on the [Aspose.3D documentation site](https://docs.aspose.org/3d/java/). - **Knowledge Base** -- practical how-to articles and troubleshooting tips in the [Aspose.3D KB](https://kb.aspose.org/3d/java/). - **API Reference** -- detailed class and method reference at the [Aspose.3D API Reference](https://reference.aspose.org/3d/java/). - **Source Code** -- browse and contribute on [GitHub](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java). - **Maven Central** -- the package is published as on Maven Central. ## Common Use Cases Here are some practical scenarios where Aspose.3D FOSS for Java fits well: ### Format Conversion Pipelines Many teams receive 3D assets in one format but need them in another. A design team might work in FBX while the web team needs glTF. The library lets you build automated conversion pipelines: ```java // Convert all incoming FBX assets to GLB for the web team Scene scene = Scene.fromFile("asset.fbx"); GltfSaveOptions opts = new GltfSaveOptions(FileContentType.BINARY); scene.save("asset.glb", opts); ``` ### 3D Model Inspection and Validation Before integrating a 3D asset into your application, you may want to validate its contents -- checking node counts, verifying geometry, or confirming that expected elements are present: ```java Scene scene = Scene.fromFile("model.obj"); int nodeCount = scene.getRootNode().getChildNodes().size(); System.out.println("Top-level nodes: " + nodeCount); for (Node child : scene.getRootNode().getChildNodes()) { if (child.getEntity() instanceof Mesh) { Mesh mesh = (Mesh) child.getEntity(); System.out.println(child.getName() + ": " + mesh.getControlPoints().size() + " vertices"); } } ``` ### Scene Assembly You can load multiple models and combine them into a single scene: ```java Scene scene = new Scene(); Scene part1 = Scene.fromFile("chassis.obj"); Scene part2 = Scene.fromFile("wheels.obj"); // Add nodes from each part into the combined scene for (Node child : part1.getRootNode().getChildNodes()) { scene.getRootNode().getChildNodes().add(child); } for (Node child : part2.getRootNode().getChildNodes()) { scene.getRootNode().getChildNodes().add(child); } scene.save("assembled.gltf"); ``` ## What's Next In upcoming posts, we will cover: - A deep dive into the key features of the scene-graph API, materials, and math utilities. - A practical guide to working with each supported 3D format -- OBJ, STL, glTF, and FBX -- including load/save options and batch conversion patterns. Stay tuned, and feel free to explore the library and share your feedback on GitHub. ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) - [Aspose.3D for Java — Enterprise Product](https://products.aspose.com/3d/java/) --- # Key Features of Aspose.3D FOSS for Java URL: https://blog.aspose.org/3d/java/3d-java-scene-graph-materials/ Explore the key features of Aspose.3D FOSS for Java including the scene graph API, material system, transforms, and math utilities with code examples. --- Product: Aspose.3D Platform: java Page Type: index Canonical URL: https://blog.aspose.org/3d/java/3d-java-scene-graph-materials/ --- # Key Features of Aspose.3D FOSS for Java Aspose.3D FOSS for Java provides a comprehensive API for working with 3D scenes, nodes, materials, and geometry. This post explores the key features that make up the library, with code examples for each area. All examples assume the following import: ```java import com.aspose.threed.*; ``` And the Maven dependency: ## Scene Graph API The scene graph is the foundation of Aspose.3D FOSS for Java. Every 3D model -- whether loaded from a file or built programmatically -- is represented as a tree of nodes rooted in a `Scene` object. ### Scene The `Scene` class is the entry point for all operations. You can create an empty scene or load one from a file: ```java // Empty scene Scene scene = new Scene(); // Load from file Scene loaded = Scene.fromFile("model.obj"); // Load with explicit options Scene fromStl = Scene.fromFile("part.stl", new StlLoadOptions()); ``` The root of the node tree is accessed via `getRootNode()`. ### Node A `Node` represents a named position in the scene tree. Nodes can have children, forming a hierarchy. Each node carries a local `Transform` and a computed `GlobalTransform`. ```java Scene scene = new Scene(); // Create a child node under the root Node box = scene.getRootNode().createChildNode("Box"); // Create a nested hierarchy Node arm = scene.getRootNode().createChildNode("Arm"); Node hand = arm.createChildNode("Hand"); Node finger = hand.createChildNode("Finger"); ``` You can also construct nodes independently and attach them later: ```java Node standalone = new Node("Standalone"); scene.getRootNode().getChildNodes().add(standalone); ``` ### Entity and Mesh An `Entity` is an abstract base class for anything that can be attached to a node -- geometry, cameras, and lights. The most common entity type is `Mesh`, which holds polygonal geometry (vertices, faces, and normals). ```java Scene scene = Scene.fromFile("cube.obj"); // Traverse nodes and inspect entities for (Node child : scene.getRootNode().getChildNodes()) { Entity entity = child.getEntity(); if (entity instanceof Mesh) { Mesh mesh = (Mesh) entity; System.out.println("Node: " + child.getName()); System.out.println(" Vertices: " + mesh.getControlPoints().size()); } } ``` ### Camera Cameras are entities that attach to nodes: ```java Scene scene = new Scene(); Node cameraNode = scene.getRootNode().createChildNode("MainCamera"); // Camera entity can be assigned to the node ``` > **Note:** The `Camera` class in the Java edition is a minimal stub with constructors only. Camera entities attached to nodes are **not written** when exporting to glTF or any other format — the glTF exporter processes only `Mesh` entities. Do not rely on camera data being preserved in exported files. > **Note:** The `Light` class is not available in the Java edition. Scene lighting data from imported files is stored as generic `Entity` objects. ## Format-Agnostic Load and Save One of the strengths of the library is that the scene graph is format-independent. You load from any supported format, manipulate the scene through a single API, and save to any supported format. ```java // Load OBJ, save as glTF Scene scene = Scene.fromFile("input.obj"); scene.save("output.gltf"); // Load FBX, save as STL (FBX is import only) Scene scene2 = Scene.fromFile("character.fbx"); scene2.save("character.stl"); // Load STL, save as GLB Scene scene3 = Scene.fromFile("part.stl", new StlLoadOptions()); GltfSaveOptions opts = new GltfSaveOptions(FileContentType.BINARY); scene3.save("part.glb", opts); ``` The format is determined by the file extension. You can also pass explicit save options to control the output: ```java GltfSaveOptions opts = new GltfSaveOptions(); opts.setPrettyPrint(true); scene.save("output.gltf", opts); ``` ## Materials Aspose.3D FOSS for Java provides a PBR (Physically Based Rendering) material model via `PbrMaterial`. This is the only concrete material class in the Java edition. ### PbrMaterial A physically based rendering material that uses albedo, metalness, and roughness parameters. This is the standard material model for glTF and modern real-time engines. ```java PbrMaterial pbr = new PbrMaterial(); pbr.setAlbedo(new Vector4(0.8, 0.2, 0.2, 1.0)); // Red-ish base color pbr.setMetallicFactor(0.0); // Non-metallic pbr.setRoughnessFactor(0.5); // Medium roughness ``` Material preservation across formats depends on the capabilities of the target format. PBR materials map naturally to glTF and GLB output. ## Transform and Spatial Every `Node` in the scene graph has a `Transform` that defines its position, rotation, and scale relative to its parent. ### Local Transform ```java Scene scene = new Scene(); Node node = scene.getRootNode().createChildNode("TestNode"); Transform t = node.getTransform(); t.setTranslation(1, 2, 3); // Position t.setScale(2, 2, 2); // Uniform scale t.setEulerAngles(0, 45, 0); // Euler rotation in degrees ``` ### Global Transform The `GlobalTransform` is the computed world-space transform, taking the entire parent chain into account. This is read-only and updates automatically. ```java Node parent = scene.getRootNode().createChildNode("Parent"); parent.getTransform().setTranslation(10, 0, 0); Node child = parent.createChildNode("Child"); child.getTransform().setTranslation(5, 0, 0); // Child's global position is (15, 0, 0) GlobalTransform global = child.getGlobalTransform(); ``` This parent-child transform inheritance follows the standard scene-graph pattern used by 3D engines and DCC tools. ## Math Utilities The library includes core math types for 3D operations. ### Vector3 A three-component vector used for positions, directions, normals, and colors. ```java Vector3 a = new Vector3(1, 0, 0); Vector3 b = new Vector3(0, 1, 0); // Addition Vector3 sum = Vector3.add(a, b); // (1, 1, 0) ``` ### Matrix4 A 4x4 transformation matrix for combining translation, rotation, and scale into a single operation. ```java Matrix4 mat = new Matrix4(); // Matrix4 is used internally by transforms // and can be retrieved from GlobalTransform ``` ### Quaternion A rotation representation that avoids gimbal lock and interpolates smoothly. Quaternions are used internally by the transform system. ### BoundingBox An axis-aligned bounding box for spatial queries, collision checks, and scene analysis. ```java BoundingBox bbox = new BoundingBox(); // BoundingBox can be constructed directly with min/max Vector3 values ``` > **Note:** `Node.getBoundingBox()` and `Entity.getBoundingBox()` are not yet implemented. Both return an empty `BoundingBox` (with sentinel `Double.MAX_VALUE` / `Double.MIN_VALUE` values) regardless of the mesh geometry. Do not use these methods to compute actual geometry bounds in this version. ## Known Limitations It is worth noting that `Scene.render` is **not supported** in the FOSS edition. Calling it will throw an `UnsupportedOperationException`. The library is designed for file-based 3D processing -- loading, transforming, and saving -- rather than real-time rendering. ## Summary The key features of Aspose.3D FOSS for Java break down into five areas: | Area | Classes | Purpose | |---|---|---| | Scene Graph | `Scene`, `Node`, `Entity`, `Mesh`, `Camera` | Hierarchical model representation | | Formats | Load/Save options for OBJ, STL, glTF/GLB; Load for FBX | Format-agnostic I/O | | Materials | `PbrMaterial` | Surface appearance (PBR) | | Transforms | `Transform`, `GlobalTransform` | Spatial positioning | | Math | `Vector3`, `Matrix4`, `Quaternion`, `BoundingBox` | 3D math primitives | In the next post, we will walk through practical format-by-format tutorials covering OBJ, STL, glTF, and FBX with detailed load and save options. ## Getting Started - [Getting Started](https://docs.aspose.org/3d/java/getting-started/) - [Developer Guide](https://docs.aspose.org/3d/java/developer-guide/) - [KB Articles](https://kb.aspose.org/3d/java/) - [API Reference](https://reference.aspose.org/3d/java/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # 3D Scene Management in Java with Aspose.3D FOSS URL: https://blog.aspose.org/3d/java/3d-scene-management-java/ Learn how to create, manipulate, and export 3D scenes in Java using Aspose.3D FOSS. Build node hierarchies, construct meshes, apply transforms, and save to FBX, glTF, OBJ, and STL. --- Product: Aspose.3D Platform: java Page Type: index Canonical URL: https://blog.aspose.org/3d/java/3d-scene-management-java/ --- # 3D Scene Management in Java with Aspose.3D FOSS ## Introduction Working with 3D content in Java typically requires choosing between heavyweight game engines and bare-bones math libraries. The `aspose-3d-foss` package offers a middle ground: a focused scene-graph API that handles file I/O, node hierarchies, mesh construction, and coordinate transforms without pulling in a rendering pipeline or a native dependency chain. Aspose.3D FOSS for Java is an open-source library distributed under the MIT license. It provides 80 classes spanning scene management, geometry, materials, and format conversion. The library reads FBX, glTF/GLB, Wavefront OBJ, and STL, and writes glTF/GLB, OBJ, and STL (FBX export is not implemented), making it practical for server-side 3D processing, build-tool integrations, and data-conversion pipelines that run on Java 21 or later. This post walks through the scene-management capabilities in the library: how to build a scene from scratch, populate it with geometry and transforms, and export the result to disk. --- ## What's Included ### Scene Graph Basics The `Scene` class is the root container for every 3D document. It holds a root `Node`, asset metadata, animation clips, and sub-scenes. You can create an empty scene and then populate it, or load an existing file with `Scene.fromFile`. ```java import com.aspose.threed.Scene; import com.aspose.threed.Node; Scene scene = new Scene(); Node root = scene.getRootNode(); // Add named child nodes to build a hierarchy Node chassis = root.createChildNode("Chassis"); Node wheel = chassis.createChildNode("FrontLeftWheel"); ``` Every `Node` can hold an `Entity` (such as a `Mesh` or `Camera`), a `Transform`, a list of materials, and further child nodes. The tree structure mirrors the scene-graph pattern used by most 3D authoring tools. ### Mesh Construction The `Mesh` class lets you define geometry from control points and polygon indices. You add vertices with `addControlPoint`, then connect them into faces with `createPolygon`. ```java import com.aspose.threed.Mesh; Mesh box = new Mesh("Box"); // Define eight corners of a cube box.addControlPoint(0, 0, 0); box.addControlPoint(1, 0, 0); box.addControlPoint(1, 1, 0); box.addControlPoint(0, 1, 0); box.addControlPoint(0, 0, 1); box.addControlPoint(1, 0, 1); box.addControlPoint(1, 1, 1); box.addControlPoint(0, 1, 1); // Create quad faces box.createPolygon(0, 1, 2, 3); // back box.createPolygon(4, 5, 6, 7); // front box.createPolygon(0, 4, 7, 3); // left box.createPolygon(1, 5, 6, 2); // right box.createPolygon(3, 2, 6, 7); // top box.createPolygon(0, 1, 5, 4); // bottom scene.getRootNode().createChildNode("Box", box); ``` The mesh API includes `triangulate()`, `optimize(removeVertices)`, and Boolean operations (`union`, `difference`, `intersect`), but these methods are stubs in the current release — they return a clone of the input mesh without performing the named operation. ### Transforms and Positioning Each `Node` carries a `Transform` that controls its local translation, rotation, and scale. These compose through the hierarchy so that moving a parent node moves all its children. ```java import com.aspose.threed.Transform; import com.aspose.threed.Node; Node node = scene.getRootNode().createChildNode("Shifted"); Transform t = node.getTransform(); t.setTranslation(5.0, 0.0, -3.0); t.setScale(2.0, 2.0, 2.0); t.setEulerAngles(0, 45.0, 0); ``` For absolute positioning queries, call `node.getGlobalTransform()` to retrieve the composed `GlobalTransform`, or `node.evaluateGlobalTransform(true)` to get a `Matrix4` that includes geometric offsets. ### PBR Materials The `PbrMaterial` class provides physically-based rendering properties: albedo color, metallic factor, roughness, emissive color, and transparency. Assign a material to a node when creating the child. ```java import com.aspose.threed.PbrMaterial; import com.aspose.threed.Vector4; import com.aspose.threed.Vector3; PbrMaterial mat = new PbrMaterial("RedMetal"); mat.setAlbedo(new Vector4(0.9, 0.1, 0.1, 1.0)); mat.setMetallicFactor(0.8); mat.setRoughnessFactor(0.3); mat.setEmissiveColor(new Vector3(0, 0, 0)); scene.getRootNode().createChildNode("Part", box, mat); ``` ### Format Detection The `FileFormat` class provides static lookup and detection utilities. You can resolve a format by file extension or probe a stream to identify unknown files. ```java import com.aspose.threed.FileFormat; FileFormat fmt = FileFormat.getFormatByExtension("model.glb"); boolean canRead = fmt.getCanImport(); boolean canWrite = fmt.getCanExport(); ``` ### Coordinate-System Conversion `AxisSystem` lets you define the up-axis, front-axis, and handedness of a coordinate system, then compute a `Matrix4` to transform geometry between conventions (for example, from a Z-up right-handed system to a Y-up left-handed one). ```java import com.aspose.threed.AxisSystem; import com.aspose.threed.Axis; import com.aspose.threed.CoordinateSystem; import com.aspose.threed.Matrix4; AxisSystem source = new AxisSystem( CoordinateSystem.RIGHT_HANDED, Axis.Z_AXIS, Axis.Y_AXIS); AxisSystem target = new AxisSystem( CoordinateSystem.LEFT_HANDED, Axis.Y_AXIS, Axis.Z_AXIS); Matrix4 conversion = source.transformTo(target); ``` --- ## Quick Start Add the Maven dependency: Build a simple scene and export it: ```java import com.aspose.threed.Scene; import com.aspose.threed.Mesh; import com.aspose.threed.Node; import com.aspose.threed.StlSaveOptions; import com.aspose.threed.FileContentType; Scene scene = new Scene(); Mesh mesh = new Mesh("Triangle"); mesh.addControlPoint(0, 0, 0); mesh.addControlPoint(1, 0, 0); mesh.addControlPoint(0, 1, 0); mesh.createPolygon(0, 1, 2); scene.getRootNode().createChildNode("Shape", mesh); StlSaveOptions opts = new StlSaveOptions(FileContentType.BINARY); scene.save("output.stl", opts); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | FBX (ASCII and Binary, 6.x-7.x) | `.fbx` | Yes | No | | glTF 1.0 / 2.0 | `.gltf` | Yes | Yes | | glTF Binary | `.glb` | Yes | Yes | | Wavefront OBJ | `.obj` | Yes | Yes | | STL (ASCII and Binary) | `.stl` | Yes | Yes | Each format has dedicated `LoadOptions` and `SaveOptions` subclasses (for example, `FbxLoadOptions`, `GltfSaveOptions`, `StlSaveOptions`) that expose format-specific settings such as coordinate-system flipping and content type selection. --- ## Open Source & Licensing Aspose.3D FOSS for Java is released under the MIT license. The source code is available on GitHub at [Aspose.3D-FOSS-for-Java](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java). You can use, modify, and redistribute the library in commercial and non-commercial projects without restriction. --- ## Getting Started - [Developer Guide](https://docs.aspose.org/3d/java/) -- API walkthroughs and usage patterns - [Knowledge Base](https://kb.aspose.org/3d/java/) -- How-to articles and FAQs - [API Reference](https://reference.aspose.org/3d/java/) -- Full class and method documentation ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Working with 3D File Formats in Java Using Aspose.3D FOSS URL: https://blog.aspose.org/3d/java/convert-obj-stl-gltf-java/ A practical guide to loading, converting, and saving OBJ, STL, glTF, and FBX files in Java using Aspose.3D FOSS with format-specific options and batch conversion. --- Product: Aspose.3D Platform: java Page Type: index Canonical URL: https://blog.aspose.org/3d/java/convert-obj-stl-gltf-java/ --- # Working with 3D File Formats in Java Using Aspose.3D FOSS ## Introduction Aspose.3D FOSS for Java supports four 3D file formats: **OBJ**, **STL**, **glTF** (including GLB binary variant), and **FBX** (import only). This post is a practical, format-by-format guide showing how to load and save each one, what options are available, and how to convert between them. All examples use the `com.aspose.threed.*` package: ```java import com.aspose.threed.*; ``` Maven dependency: ## Format Landscape Before diving in, here is a quick overview of the four supported formats and their typical use cases. | Format | Extension | Import | Export | Material Support | Scene Hierarchy | |---|---|---|---|---|---| | OBJ | `.obj` | Yes | Yes | Basic (MTL files) | Flat | | STL | `.stl` | Yes | Yes | None | Flat | | glTF | `.gltf` / `.glb` | Yes | Yes | PBR | Full | | FBX | `.fbx` | Yes | No | Rich | Full | OBJ, STL, and glTF support bidirectional conversion. GLB (binary glTF) is a variant of the glTF format produced by passing `FileContentType.BINARY` to the `GltfSaveOptions` constructor. FBX files are loaded using `Scene.fromFile`. ## OBJ: Wavefront Object OBJ is one of the most widely supported 3D mesh formats. It stores geometry as plain text, with an optional `.mtl` companion file for materials. ### Loading OBJ Files The simplest approach is to pass the file path directly: ```java Scene scene = Scene.fromFile("model.obj"); ``` For more control, use `ObjLoadOptions`: ```java ObjLoadOptions opts = new ObjLoadOptions(); Scene scene = Scene.fromFile("model.obj", opts); ``` When the OBJ file references an MTL file (via a `mtllib` directive), the library will attempt to load material definitions from it automatically. The MTL file should be in the same directory as the OBJ file or at the path specified in the directive. ### Saving as OBJ To convert any loaded scene to OBJ format, use the `save()` method with an `.obj` file path: ```java Scene scene = Scene.fromFile("input.fbx"); scene.save("output.obj"); ``` ### OBJ Use Cases - Exchanging mesh data between different 3D tools. - Importing models from asset libraries that distribute in OBJ format. - Quick inspection of geometry without complex scene hierarchies. ## STL: Stereolithography STL is the standard format for 3D printing. It represents raw triangulated geometry without materials, colors, or scene hierarchy. STL files come in two variants: ASCII (human-readable) and binary (compact). ### Loading STL Files Load an STL file using `Scene.fromFile`, with or without explicit `StlLoadOptions`: ```java // Simple load Scene scene = Scene.fromFile("part.stl"); // With explicit options StlLoadOptions opts = new StlLoadOptions(); Scene scene = Scene.fromFile("part.stl", opts); ``` ### Saving as STL Save a loaded scene to STL using a direct `save()` call or with explicit `StlSaveOptions` for binary-format control: ```java Scene scene = Scene.fromFile("model.obj"); scene.save("output.stl"); ``` For granular control over the output file, use `StlSaveOptions` to configure the binary format and other export parameters: ```java StlSaveOptions opts = new StlSaveOptions(); scene.save("output.stl", opts); ``` ### STL Considerations - STL stores only triangle geometry. Materials, textures, and scene hierarchy are outside the format spec and are omitted on export. - STL export does **not** triangulate automatically. Binary STL writes only the first 3 vertices of each polygon face; quad and n-gon faces are silently truncated. ASCII STL writes all vertex indices per face, producing malformed output for non-triangle faces. Always use pre-triangulated meshes (all-triangle faces) when exporting to STL. - Binary STL is significantly smaller than ASCII STL for large models. - STL is the format of choice when the target is a 3D printer or slicer software. ## glTF: GL Transmission Format glTF is a modern format designed for efficient transmission and loading of 3D content, particularly on the web and in real-time applications. It supports PBR materials, scene hierarchies, and animations. ### Saving as glTF The basic save uses the file extension to determine the format: ```java scene.save("output.gltf"); ``` For detailed control, use `GltfSaveOptions`: ```java GltfSaveOptions opts = new GltfSaveOptions(); opts.setPrettyPrint(true); scene.save("output.gltf", opts); ``` #### GltfSaveOptions Details | Method | Purpose | |---|---| | `setPrettyPrint(boolean)` | Format the output JSON with indentation for readability. Set to `false` for smaller file size in production. | ### glTF Use Cases - Web-based 3D viewers (three.js, Babylon.js). - Real-time applications and game engines. - Preserving PBR material definitions across tools. ## FBX: Filmbox FBX is a proprietary format by Autodesk that is widely used in game development and digital content creation. Aspose.3D FOSS for Java reads FBX files via `Scene.fromFile` with `FbxLoadOptions` for additional control. > **Binary FBX only.** The FBX importer reads binary FBX files only. Passing an ASCII FBX file throws `ImportException`. Node hierarchy and material extraction from complex FBX scenes may be partial. Animations and rigging data require further verification. ### Loading FBX Files Load binary FBX files using `Scene.fromFile`, optionally passing `FbxLoadOptions` for additional control: ```java Scene scene = Scene.fromFile("character.fbx"); // With options FbxLoadOptions opts = new FbxLoadOptions(); Scene scene = Scene.fromFile("character.fbx", opts); ``` ### Exporting a Loaded FBX Scene FBX is import-only. To export FBX content, load it with `Scene.fromFile` and save to a supported output format such as OBJ, STL, or glTF: ```java Scene scene = Scene.fromFile("character.fbx"); // Save as GLB GltfSaveOptions opts = new GltfSaveOptions(FileContentType.BINARY); scene.save("character.glb", opts); ``` ### FBX Use Cases - Importing static mesh assets from Autodesk tools (Maya, 3ds Max) and converting to other formats. - Loading binary FBX geometry and re-exporting to glTF/GLB, OBJ, or STL. ## Batch Conversion A common workflow is converting an entire directory of files from one format to another. Here is a pattern for batch conversion: ```java import com.aspose.threed.*; import java.io.File; public class BatchConvert { public static void main(String[] args) throws Exception { File inputDir = new File("models/obj"); File outputDir = new File("models/gltf"); outputDir.mkdirs(); GltfSaveOptions saveOpts = new GltfSaveOptions(); saveOpts.setPrettyPrint(true); File[] objFiles = inputDir.listFiles( (dir, name) -> name.toLowerCase().endsWith(".obj") ); if (objFiles == null) return; for (File objFile : objFiles) { String baseName = objFile.getName() .replaceFirst("\\.obj$", ""); Scene scene = Scene.fromFile(objFile.getAbsolutePath()); String outPath = new File(outputDir, baseName + ".gltf") .getAbsolutePath(); scene.save(outPath, saveOpts); System.out.println("Converted: " + objFile.getName() + " -> " + baseName + ".gltf"); } } } ``` This loads every `.obj` file in a directory, converts each to glTF with pretty-printed output, and saves the results. You can adapt this pattern for any source and target format combination. ## Cross-Format Conversion Reference The following table shows what to expect when converting between formats. | From | To | Geometry | Materials | Hierarchy | Notes | |---|---|---|---|---|---| | OBJ | STL | Preserved | Lost | N/A | STL has no material support | | OBJ | glTF/GLB | Preserved | Converted to PBR | Flat | MTL materials mapped where possible | | STL | OBJ | Preserved | None | N/A | No materials in source | | STL | glTF/GLB | Preserved | Default | Flat | Default material applied | | glTF | OBJ | Preserved | Simplified | Flattened | PBR to basic material | | glTF | STL | Preserved | Lost | Flattened | Geometry only | | FBX | OBJ | Preserved | Simplified | Flattened | Material simplification | | FBX | STL | Preserved | Lost | Flattened | Geometry only | | FBX | glTF/GLB | Preserved | Converted to PBR | Preserved | Good fidelity | ### General Conversion Guidelines - **Geometry** is generally preserved across format pairs, with one important exception: when exporting to STL, meshes must consist entirely of triangle faces. Binary STL silently truncates quad and n-gon faces to their first 3 vertices; ASCII STL produces malformed output for non-triangle faces. - **Materials** survive best between glTF and FBX-imported scenes that include material data. Converting to STL always drops materials. Converting to OBJ simplifies materials to the basic MTL model. - **Scene hierarchy** is preserved between glTF-format files. OBJ and STL produce flat mesh structures without hierarchy. FBX hierarchy and material extraction are partially supported; complex scenes may require additional handling. ## Putting It All Together Here is a complete example that loads an OBJ file, inspects its nodes, and exports to both glTF and GLB: ```java import com.aspose.threed.*; public class FormatWorkflow { public static void main(String[] args) throws Exception { // Load Scene scene = Scene.fromFile("input.obj"); // Inspect System.out.println("Nodes in scene:"); for (Node child : scene.getRootNode().getChildNodes()) { System.out.println(" " + child.getName()); Transform t = child.getTransform(); System.out.println(" Translation: " + t.getTranslation()); } // Export to glTF with options GltfSaveOptions gltfOpts = new GltfSaveOptions(); gltfOpts.setPrettyPrint(true); scene.save("output.gltf", gltfOpts); // Export to GLB (binary glTF) GltfSaveOptions glbOpts = new GltfSaveOptions(FileContentType.BINARY); scene.save("output.glb", glbOpts); System.out.println("Export complete."); } } ``` ## Summary Aspose.3D FOSS for Java gives you a consistent API across multiple formats. The key points: - **OBJ** -- simple mesh interchange with basic materials. - **STL** -- geometry-only format for 3D printing pipelines. - **glTF / GLB** -- modern PBR-capable format for web and real-time use. Pass `FileContentType.BINARY` to the `GltfSaveOptions` constructor for GLB output. - **FBX** -- import only; rich format for loading assets from game engines and DCC tools. Use format-specific load and save option classes (`ObjLoadOptions`, `StlLoadOptions`, `StlSaveOptions`, `GltfLoadOptions`, `GltfSaveOptions`, `FbxLoadOptions`) when you need fine-grained control over the import or export process. For more details, visit the [Aspose.3D documentation](https://docs.aspose.org/3d/java/) or browse the source on [GitHub](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-Java). ## Quick Start Add the Maven dependency and load your first 3D file: ```java import com.aspose.threed.*; import com.aspose.threed.export.SaveFormat; Scene scene = Scene.fromFile("model.obj"); scene.save("output.gltf"); ``` ## Getting Started Install Aspose.3D FOSS for Java via Maven and start working with 3D files in a single import statement: ```java import com.aspose.threed.*; ``` No Microsoft or Autodesk software is required. All reading and writing happens in the local Java process with no external dependencies. - [Developer Guide](https://docs.aspose.org/3d/java/) - [API Reference](https://reference.aspose.org/3d/java/) - [Knowledge Base](https://kb.aspose.org/3d/java/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.3D FOSS for .NET URL: https://blog.aspose.org/3d/net/ --- Product: Aspose.3D Platform: net Page Type: index Canonical URL: https://blog.aspose.org/3d/net/ --- # Aspose.3D FOSS for .NET ## Related Topics - [Introducing Aspose.3D FOSS for .NET](https://blog.aspose.org/3d/net/3d-dotnet-obj-stl-gltf-library/) - [Key Features of Aspose.3D FOSS for .NET](https://blog.aspose.org/3d/net/3d-dotnet-primitives-mesh-ops/) - [3D Utilities for .NET with Aspose.3D FOSS](https://blog.aspose.org/3d/net/3d-utilities-net/) - [Working with 3D File Formats in .NET Using Aspose.3D FOSS](https://blog.aspose.org/3d/net/convert-obj-stl-gltf-dotnet/) - [Scene Entities In Net -- Aspose.3D FOSS for .NET](https://blog.aspose.org/3d/net/scene-entities-in-net/) --- # Introducing Aspose.3D FOSS for .NET URL: https://blog.aspose.org/3d/net/3d-dotnet-obj-stl-gltf-library/ Aspose.3D FOSS for .NET is an open-source, MIT-licensed library for loading, manipulating, and saving 3D file formats including OBJ, STL, glTF, FBX, Collada, and 3MF. --- Product: Aspose.3D Platform: net Page Type: index Canonical URL: https://blog.aspose.org/3d/net/3d-dotnet-obj-stl-gltf-library/ --- # Introducing Aspose.3D FOSS for .NET We are excited to announce the availability of **Aspose.3D FOSS for .NET** -- a free, open-source library for working with 3D file formats in .NET applications. Built as a pure C# solution with no native dependencies, the library targets .NET 10.0 and later, making it accessible to a broad range of projects and environments. This post walks through what the library offers, how to get started, and where to go from here. ## What Is Aspose.3D FOSS for .NET? Aspose.3D FOSS for .NET is a lightweight 3D file processing library published under the **MIT license**. It provides a scene-graph API that lets you load, inspect, transform, and save 3D models across several widely used formats. The library is entirely written in C# and requires no external native binaries or platform-specific configurations. The source code is available on GitHub: **[https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-NET](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-NET)** ### Key Highlights - **Pure C#** -- no P/Invoke, no native libraries, no platform restrictions. - **.NET 10.0+** compatible. - **MIT licensed** -- use it in personal, commercial, or proprietary projects without restrictions. - **Scene-graph architecture** -- a familiar tree of nodes, meshes, cameras, and materials. - **Multi-format support** -- read and write OBJ, STL, glTF 2.0, GLB, FBX, Collada, and 3MF files. ## Quick Start ### NuGet Installation Add the NuGet package to your project: ### Your First Conversion The simplest use case is loading a 3D file in one format and saving it in another. Here is a two-line conversion from OBJ to STL: ```csharp using Aspose.ThreeD; var scene = new Scene(); scene.Open("cube.obj"); scene.Save("output.stl"); ``` The `Scene` class is the central entry point. Call `scene.Open()` with a file path to load a model, then call `Save()` with the target path. The library infers the format from the file extension. ### Building a Scene from Scratch You can also construct scenes programmatically: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; var scene = new Scene(); var box = new Box(2, 2, 2); var node = scene.RootNode.CreateChildNode("Box", box); node.Transform.Translation = new Vector3(1, 2, 3); scene.Save("scene.gltf"); ``` This creates a new scene, adds a box primitive as a child node under the root, positions it at coordinates (1, 2, 3), and exports the result as a glTF file. ### Loading with Format-Specific Options When you need finer control over the loading process, each format provides a dedicated options class. For example, loading an STL file with explicit options: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Formats; var scene = new Scene(); var opts = new StlLoadOptions(); scene.Open("part.stl", opts); // Inspect the loaded scene Console.WriteLine("Root children: " + scene.RootNode.ChildNodes.Count); // Re-export as OBJ scene.Save("part.obj"); ``` The `scene.Open()` method accepts any of the load option types: `ObjLoadOptions`, `StlLoadOptions`, `GltfLoadOptions`, or `FbxLoadOptions`. ### Traversing the Scene Graph Once a scene is loaded, you can walk the node tree to inspect or modify its contents: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; var scene = new Scene(); scene.Open("model.gltf"); foreach (var child in scene.RootNode.ChildNodes) { Console.WriteLine("Node: " + child.Name); Console.WriteLine(" Translation: " + child.Transform.Translation); if (child.Entity is Mesh mesh) { Console.WriteLine(" Vertices: " + mesh.ControlPoints.Count); } } ``` This pattern is useful for debugging, generating reports about model contents, or selectively modifying parts of a scene before re-exporting. ### Applying Transforms Positioning nodes in 3D space is done through the `Transform` property on each `Node`: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; var scene = new Scene(); var parent = scene.RootNode.CreateChildNode("Parent"); parent.Transform.Translation = new Vector3(10, 0, 0); var child = parent.CreateChildNode("Child"); child.Transform.Translation = new Vector3(5, 0, 0); child.Transform.Scaling = new Vector3(2, 2, 2); // Child's world position is (15, 0, 0) due to // parent-child transform inheritance scene.Save("transformed.gltf"); ``` Transforms follow the standard parent-child inheritance model: a child's world-space position is the combination of its local transform and all ancestor transforms up to the root. ## What's Included The library ships with a focused set of capabilities designed around the 3D scene-graph model. ### Scene Graph The scene graph is the backbone of the API. Every 3D file is represented as a tree structure: | Class | Role | |---|---| | `Scene` | Top-level container; the root of the scene graph | | `Node` | A named position in the tree; holds transforms and child nodes | | `Entity` | Abstract base for visual objects attached to nodes | | `Mesh` | Polygonal geometry -- vertices, faces, normals | | `Camera` | Virtual camera definition | | `Transform` | Local translation, rotation, and scale for a node | | `GlobalTransform` | Computed world-space transform | ### Built-In Primitives The .NET edition includes parametric shape classes that can be attached to nodes directly or converted to `Mesh`: - **Box** -- axis-aligned box with configurable width, height, and depth. - **Sphere** -- parametric sphere with configurable radius. - **Cylinder** -- parametric cylinder with configurable radii and height. ```csharp var sphere = new Sphere(1); var mesh = sphere.ToMesh(); Console.WriteLine("Vertices: " + mesh.ControlPoints.Count); ``` ### Materials The library provides multiple material types: - **LambertMaterial** -- classic diffuse-only material with ambient, diffuse, emissive, and reflective colour components. - **PhongMaterial** -- extends Lambert with specular highlights and shininess. - **PbrMaterial** -- physically based rendering material with base color, metallic, roughness, occlusion, and texture slots. ### Math Utilities The `Aspose.ThreeD` namespace includes essential math primitives: - **FVector3** -- single-precision 3-component float vector; exposes `Zero`, `One`, `UnitX`, `UnitY`, and `UnitZ` static properties (this API surface does not expose public named X/Y/Z instance fields). `Transform.Translation` and `Transform.Scaling` use the double-precision `Vector3` type instead. - **Vector4** (`Aspose.ThreeD.Utilities`) -- double-precision 4-component vector for control points and normals; exposes a `Length` property (this API surface does not expose public named x/y/z/w fields). `Mesh.ControlPoints` uses this double-precision Utilities variant. - **Matrix4** -- 4x4 transformation matrix. - **Quaternion** -- rotation representation. Used by `Transform.Rotation`. - **BoundingBox** -- axis-aligned bounding box for spatial queries. ```csharp var a = new FVector3(1, 0, 0); var b = new FVector3(0, 1, 0); // Vector operations for spatial computations ``` ### Load and Save Options Each format has dedicated option classes that let you control import and export behavior: | Format | Load Options | Save Options | |---|---|---| | OBJ | `ObjLoadOptions` | `ObjSaveOptions` | | STL | `StlLoadOptions` | `StlSaveOptions` | | glTF / GLB | `GltfLoadOptions` | `GltfSaveOptions` | | FBX | `FbxLoadOptions` | `FbxSaveOptions` | | 3MF | — | `Microsoft3MFSaveOptions` | For example, to load an OBJ file with coordinate flipping and normal normalization: ```csharp var opts = new ObjLoadOptions(); opts.FlipCoordinateSystem = true; opts.NormalizeNormal = true; scene.Open("model.obj", opts); ``` ## Supported Formats The following table summarizes the formats that Aspose.3D FOSS for .NET can read and write. | Format | Extension | Import | Export | Notes | |---|---|---|---|---| | OBJ | `.obj` | Yes | Yes | With MTL materials | | STL | `.stl` | Yes | Yes | Binary + ASCII | | glTF | `.gltf`, `.glb` | Yes | Yes | JSON format; `.glb` is the self-contained binary variant | | FBX | `.fbx` | Yes | Yes | Binary export only; ASCII export is declared but not active in this version | | COLLADA | `.dae` | Yes | Yes | | | 3MF | `.3mf` | Yes | Yes | ZIP-based 3D manufacturing format | ### Format Selection Guide Choosing the right format depends on your use case: - **OBJ** is ideal when you need maximum compatibility across 3D tools. Nearly every modeling application can read and write OBJ. It works well for mesh data exchange but carries only basic material information through companion MTL files. - **STL** is the format of choice for 3D printing workflows. It stores raw triangulated geometry without materials or scene hierarchy, which is exactly what slicer software expects. - **glTF** is the modern standard for web and real-time 3D. It supports PBR materials, full scene hierarchies, and is designed for efficient transmission. Use glTF when building web-based viewers or targeting any real-time rendering pipeline. - **FBX** is deeply integrated into game development and digital content creation workflows. It supports rich scene data including hierarchies and materials. Aspose.3D FOSS for .NET supports FBX **import and export**. Note: export produces binary FBX only — ASCII FBX export code exists in the source but is not wired to the export path in this version. - **3MF** is a modern 3D printing format that supports rich metadata, materials, and multi-object scenes in a single ZIP-based package. ### Known Limitations The `Render` method on `Scene` is **not supported** in the FOSS edition. Calling it will throw a `NotImplementedException`. The library is designed for file-based 3D processing -- loading, manipulating, transforming, and saving models -- rather than real-time rendering to a display. ## Open Source and Licensing Aspose.3D FOSS for .NET is released under the **MIT License**. This means you are free to: - Use the library in commercial and proprietary applications. - Modify the source code to fit your needs. - Distribute the library as part of your own software. There are no royalty fees, no usage limits, and no attribution requirements beyond what the MIT license specifies. The full source code is hosted on GitHub, and contributions are welcome: **[https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-NET](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-NET)** ## System Requirements | Requirement | Detail | |---|---| | .NET version | 10.0 or later | | Dependencies | None (pure C#) | | Platforms | Any platform that runs .NET | | Package manager | NuGet | ## Getting Started Here are the resources to help you get up and running: - **Documentation** -- comprehensive guides and API walkthroughs are available on the [Aspose.3D documentation site](https://docs.aspose.org/3d/net/). - **Knowledge Base** -- practical how-to articles and troubleshooting tips in the [Aspose.3D KB](https://kb.aspose.org/3d/net/). - **API Reference** -- detailed class and method reference at the [Aspose.3D API Reference](https://reference.aspose.org/3d/net/). - **Source Code** -- browse and contribute on [GitHub](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-NET). - **NuGet** -- the package is published as `Aspose.3D` on NuGet. ## Common Use Cases Here are some practical scenarios where Aspose.3D FOSS for .NET fits well: ### Format Conversion Pipelines Many teams receive 3D assets in one format but need them in another. A design team might work in FBX while the web team needs glTF. The library lets you build automated conversion pipelines: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Formats; // Convert all incoming FBX assets to GLB for the web team var scene = new Scene(); scene.Open("asset.fbx"); scene.Save("asset.glb"); ``` ### 3D Model Inspection and Validation Before integrating a 3D asset into your application, you may want to validate its contents -- checking node counts, verifying geometry, or confirming that expected elements are present: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; var scene = new Scene(); scene.Open("model.obj"); int nodeCount = scene.RootNode.ChildNodes.Count; Console.WriteLine("Top-level nodes: " + nodeCount); foreach (var child in scene.RootNode.ChildNodes) { if (child.Entity is Mesh mesh) { Console.WriteLine(child.Name + ": " + mesh.ControlPoints.Count + " vertices"); } } ``` ### Scene Assembly You can load multiple models and combine them into a single scene: ```csharp using Aspose.ThreeD; var scene = new Scene(); var part1 = new Scene(); part1.Open("chassis.obj"); var part2 = new Scene(); part2.Open("wheels.obj"); // Add nodes from each part into the combined scene foreach (var child in part1.RootNode.ChildNodes) { scene.RootNode.ChildNodes.Add(child); } foreach (var child in part2.RootNode.ChildNodes) { scene.RootNode.ChildNodes.Add(child); } scene.Save("assembled.gltf"); ``` ## What's Next In upcoming posts, we will cover: - A deep dive into the key features of the scene-graph API, materials, and math utilities. - A practical guide to working with each supported 3D format -- OBJ, STL, glTF, FBX, and 3MF -- including load/save options and batch conversion patterns. Stay tuned, and feel free to explore the library and share your feedback on GitHub. ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) - [Aspose.3D for .NET — Enterprise Product](https://products.aspose.com/3d/net/) --- # Key Features of Aspose.3D FOSS for .NET URL: https://blog.aspose.org/3d/net/3d-dotnet-primitives-mesh-ops/ Explore the key features of Aspose.3D FOSS for .NET including the scene graph API, material system, built-in primitives, transforms, and math utilities with code examples. --- Product: Aspose.3D Platform: net Page Type: index Canonical URL: https://blog.aspose.org/3d/net/3d-dotnet-primitives-mesh-ops/ --- # Key Features of Aspose.3D FOSS for .NET Aspose.3D FOSS for .NET provides a comprehensive API for working with 3D scenes, nodes, materials, built-in primitives, and mesh operations. This post explores the key features that make up the library, with code examples for each area. All examples assume the following using directive: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; using Aspose.ThreeD.Shading; ``` And the NuGet package: ## The Scene Graph The scene graph is the core data structure. A `Scene` contains a `RootNode`, and every `Node` can have child nodes and an attached `Entity` (such as a `Mesh` or `Camera`). ### Creating and Navigating Nodes Call `CreateChildNode()` on the root node to create named child nodes, and read `ChildNodes.Count` to traverse the hierarchy: ```csharp var scene = new Scene(); // Create a hierarchy var parent = scene.RootNode.CreateChildNode("Parent"); var child1 = parent.CreateChildNode("Child1"); var child2 = parent.CreateChildNode("Child2"); // Navigate the tree Console.WriteLine("Root children: " + scene.RootNode.ChildNodes.Count); Console.WriteLine("Parent children: " + parent.ChildNodes.Count); ``` ### Attaching Entities to Nodes Entities are the visual content of the scene -- meshes, cameras, and lights. Attach them using `CreateChildNode`: ```csharp var scene = new Scene(); // Create a box primitive and attach it to the scene var box = new Box(2, 2, 2); var boxNode = scene.RootNode.CreateChildNode("BoxNode", box); // Create a sphere primitive var sphere = new Sphere(1); var sphereNode = scene.RootNode.CreateChildNode("SphereNode", sphere); scene.Save("primitives.gltf"); ``` ## Built-In Primitives The .NET edition includes parametric shape classes that generate geometry without manual vertex construction: | Primitive | Description | |---|---| | `Box` | Axis-aligned box with configurable width, height, and depth | | `Sphere` | Parametric sphere with configurable radius | | `Cylinder` | Parametric cylinder with configurable top/bottom radii and height | These primitives can be attached directly to nodes or converted to a `Mesh` via `ToMesh()`: ```csharp var cylinder = new Cylinder(1, 1, 2); var mesh = cylinder.ToMesh(); Console.WriteLine("Vertices: " + mesh.ControlPoints.Count); Console.WriteLine("Polygons: " + mesh.PolygonCount); ``` ## Mesh Construction If you need full control, build meshes from scratch using control points and polygon definitions: ```csharp // Note: Mesh.ControlPoints uses Aspose.ThreeD.Utilities.Vector4 // which is double-precision with lowercase fields (x, y, z, w) using Aspose.ThreeD.Utilities; var mesh = new Mesh(); // Add vertex positions (double-precision; w=1.0 for Cartesian positions) mesh.ControlPoints.Add(new Vector4(0.0, 0.0, 0.0, 1.0)); mesh.ControlPoints.Add(new Vector4(1.0, 0.0, 0.0, 1.0)); mesh.ControlPoints.Add(new Vector4(0.5, 1.0, 0.0, 1.0)); // Define a triangle face mesh.CreatePolygon(0, 1, 2); // Attach to a scene var scene = new Scene(); scene.RootNode.CreateChildNode("triangle", mesh); scene.Save("triangle.stl"); ``` Control points use `Aspose.ThreeD.Utilities.Vector4` (double-precision) with the `w` component set to `1.0` for standard Cartesian positions. Polygons are defined by passing control-point indices to `CreatePolygon()`. ## Transforms Every `Node` has a `Transform` property that controls its local position, rotation, and scale: ```csharp var scene = new Scene(); using Aspose.ThreeD.Utilities; var node = scene.RootNode.CreateChildNode("Moved"); node.Transform.Translation = new Vector3(5, 0, 0); node.Transform.Scaling = new Vector3(2, 2, 2); ``` ### Transform Inheritance Transforms compose through the scene hierarchy. A child's world-space position is the product of all ancestor transforms: ```csharp var scene = new Scene(); using Aspose.ThreeD.Utilities; var parent = scene.RootNode.CreateChildNode("Parent"); parent.Transform.Translation = new Vector3(10, 0, 0); var child = parent.CreateChildNode("Child"); child.Transform.Translation = new Vector3(5, 0, 0); // Child's world position is (15, 0, 0) // Access via child.GlobalTransform ``` ### GlobalTransform To get a node's world-space transformation matrix (composing all ancestor transforms), call `node.EvaluateGlobalTransform(false)`: ```csharp var worldMatrix = child.EvaluateGlobalTransform(false); // worldMatrix is the world-space Matrix4 for `child` ``` > **Note:** The `Node.GlobalTransform` property exists but returns a static default value created at node construction time — it does not reflect the actual computed world transform. Always use `EvaluateGlobalTransform(bool)` to obtain the live world-space matrix. Pass `false` to exclude geometric transforms (recommended for scene-graph traversal); pass `true` to include them. ## Materials The library includes three material types with increasing complexity: ### LambertMaterial A `LambertMaterial` provides `DiffuseColor`, `AmbientColor`, and `Transparency` properties for surfaces without specular highlights: ```csharp // Material color properties use Aspose.ThreeD.Utilities.Vector3 (double-precision) using Aspose.ThreeD.Utilities; var material = new LambertMaterial("WoodMaterial"); material.DiffuseColor = new Vector3(0.6, 0.4, 0.2); material.AmbientColor = new Vector3(0.1, 0.1, 0.1); material.Transparency = 0.0; ``` ### PhongMaterial `PhongMaterial` extends Lambert with `SpecularColor`, `Shininess`, and `SpecularFactor` properties that control glossy reflections: ```csharp var material = new PhongMaterial("ShinyMetal"); material.SpecularColor = new Vector3(0.8, 0.8, 0.8); material.Shininess = 50.0; material.SpecularFactor = 32.0; ``` ### PbrMaterial `PbrMaterial` maps to the glTF 2.0 pbrMetallicRoughness schema; set `Albedo`, `MetallicFactor`, and `RoughnessFactor` to define physical appearance: ```csharp var material = new PbrMaterial(); material.Name = "GoldPBR"; material.Albedo = new Vector3(1.0, 0.8, 0.2); material.MetallicFactor = 0.9; material.RoughnessFactor = 0.1; material.OcclusionFactor = 1.0; ``` `PbrMaterial` exposes named texture properties (`AlbedoTexture`, `MetallicRoughness`, `NormalTexture`, `EmissiveTexture`, `OcclusionTexture`) of type `TextureBase` -- not string paths -- for binding image maps. `MetallicRoughness` is the combined metallic/roughness texture slot. ## Math Utilities The library includes vector, matrix, quaternion, and bounding-box types in the `Aspose.ThreeD.Utilities` namespace for 3D spatial operations: ### Vector Types | Type | Namespace | Components | Precision | Component Access | Common Use | |---|---|---|---|---|---| | `Vector2` | `Aspose.ThreeD.Utilities` | 2 | double | `U`, `V` named-field properties | UV/texture scroll and scale properties | | `Vector3` | `Aspose.ThreeD.Utilities` | 3 | double | `Item` indexer (`v[0]`, `v[1]`, `v[2]`) | General-purpose 3-component vector (material colors, `Transform.Translation`/`Transform.Scaling`) | | `Vector4` | `Aspose.ThreeD.Utilities` | 4 | double | No public named-field or indexed access exposed in this API surface | `Mesh.ControlPoints` | | `FVector3` | `Aspose.ThreeD.Utilities` | 3 | float | No public named-field or indexed access exposed in this API surface | Renderer variables (`RendererVariableManager.CameraPosition`, `.ShadowCaster`, `.WorldAmbient`) | | `FVector4` | `Aspose.ThreeD.Utilities` | 4 | float | No public named-field or indexed access exposed in this API surface | `RenderState.BlendColor` | > **Note:** The `Aspose.ThreeD.Utilities` namespace defines exactly one `Vector2`, one `Vector3`, and one `Vector4` type (all double-precision) plus the float-precision `FVector3`/`FVector4` siblings -- confirmed against `api_surface.json`, which contains no second, uppercase, single-precision `Vector2`/`Vector3`/`Vector4` family. `Mesh.ControlPoints` uses the double-precision `Vector4`. ### Quaternion `Quaternion` stores a rotation as four components. Assign to `node.Transform.Rotation` to orient a node without gimbal-lock issues: ```csharp var rotation = Quaternion.Identity; node.Transform.Rotation = rotation; ``` ### Matrix4 `Matrix4` stores a 4×4 double-precision transformation matrix, used internally by `EvaluateGlobalTransform()` to compute world-space positions: ```csharp // Matrix operations are used internally by Transform // and GlobalTransform for world-space computation ``` ### BoundingBox `BoundingBox` stores `Minimum` and `Maximum` corner points as `Vector3` values for frustum culling and spatial partitioning: ```csharp // BoundingBox stores Minimum and Maximum Vector3 corners // Used for frustum culling and spatial partitioning ``` ## Vertex Elements Meshes can carry additional per-vertex data layers beyond positions: - **VertexElementNormal** -- surface normals for lighting calculations. - **VertexElementUV** -- texture coordinates for mapping images onto geometry. - **VertexElementVertexColor** -- per-vertex RGBA colour data. Each vertex element has a `MappingMode` (per control point, per polygon vertex, or per polygon) and a `ReferenceMode` (direct values or indexed values). ## Animation Clips The `Scene` class supports named animation clips via `CreateAnimationClip()` and `GetAnimationClip()`. In the current FOSS edition, animation clip creation and lookup are functional, but keyframe data and playback are not yet implemented. ```csharp var scene = new Scene(); var clip = scene.CreateAnimationClip("Walk"); // Retrieve by name var found = scene.GetAnimationClip("Walk"); Console.WriteLine("Clip found: " + (found != null)); ``` ## What's Next Aspose.3D FOSS for .NET also supports a variety of 3D file formats including OBJ, STL, glTF, FBX, and 3MF, with extensive load options, save options, and conversion patterns for each. ## Getting Started - [Getting Started](https://docs.aspose.org/3d/net/getting-started/) - [Developer Guide](https://docs.aspose.org/3d/net/developer-guide/) - [KB Articles](https://kb.aspose.org/3d/net/) - [API Reference](https://reference.aspose.org/3d/net/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # 3D Utilities for .NET with Aspose.3D FOSS URL: https://blog.aspose.org/3d/net/3d-utilities-net/ Explore the utility classes in Aspose.3D FOSS for .NET, including mesh operations, transform builders, polygon modifiers, and primitive geometry generation. --- Product: Aspose.3D Platform: net Page Type: index Canonical URL: https://blog.aspose.org/3d/net/3d-utilities-net/ --- # 3D Utilities for .NET with Aspose.3D FOSS ## Introduction Aspose.3D FOSS is a free, open-source .NET library for working with 3D file formats. It provides a comprehensive set of utility classes that go beyond simple file conversion, enabling developers to manipulate meshes, build transforms, and generate primitive geometry programmatically. The library is released under the MIT license, making it suitable for both personal and commercial projects without restrictions. This post focuses on the utility capabilities within the library: the classes and methods you reach for when you need to triangulate a mesh, construct a transformation matrix step by step, or create parametric geometry. These building blocks complement the core scene-loading and scene-saving workflow covered in the introductory post. Whether you are processing 3D assets in a build pipeline, preparing geometry for a game engine, or converting between formats, these utilities handle the common tasks that arise in real-world 3D workflows. --- ## What's Included ### Mesh Operations The `Mesh` class represents polygon-based geometry. You can create polygons from vertex indices, query polygon sizes, triangulate faces, and optimize vertex data. The `ControlPoints` property provides direct access to the vertex positions, while `Polygons` exposes the face index arrays. ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; var scene = new Scene(); var mesh = new Mesh("CustomMesh"); // Add control points (vertices) mesh.ControlPoints.Add(new Vector4(0, 0, 0)); mesh.ControlPoints.Add(new Vector4(10, 0, 0)); mesh.ControlPoints.Add(new Vector4(10, 10, 0)); mesh.ControlPoints.Add(new Vector4(0, 10, 0)); // Create a quad polygon from four vertices mesh.CreatePolygon(0, 1, 2, 3); // Triangulate all polygons in the mesh mesh.Triangulate(); ``` ### Transform Builder The `TransformBuilder` class provides a fluent interface for constructing transformation matrices through a sequence of translate, rotate, and scale operations. You control the composition order (append or prepend) and can reset the builder to start a fresh chain. ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Utilities; var builder = new TransformBuilder(ComposeOrder.Append); // Build a combined transform: translate, then rotate, then scale builder.Translate(5, 0, 3); builder.RotateDegree(45, new Vector3(0, 1, 0)); builder.Scale(2, 2, 2); // Retrieve the composed 4x4 matrix Matrix4 result = builder.Matrix; ``` ### Polygon Modifier The `PolygonModifier` class offers static utility methods for mesh processing, including a `Triangulate` method intended to convert an n-sided polygon mesh into triangle-only geometry. In this FOSS edition, `Triangulate` is not implemented -- every overload throws `NotImplementedException` at runtime. For working triangulation, use `Mesh.Triangulate()` instead, shown in the Mesh Operations section above. ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; var scene = new Scene(); var box = new Box(2, 2, 2); Mesh boxMesh = box.ToMesh(); ``` ### Primitive Geometry Generation The library includes parametric geometry classes such as `Box`, `Sphere`, and `Cylinder`. Each primitive can be configured with dimensions and segment counts, then converted to a `Mesh` via the `ToMesh()` method for further processing or export. ```csharp using Aspose.ThreeD.Entities; // Create a parameterized sphere var sphere = new Sphere(5.0, 32, 16); Mesh sphereMesh = sphere.ToMesh(); // Create a cylinder (cone when one radius is zero) var cone = new Cylinder(0, 3.0, 6.0); Mesh coneMesh = cone.ToMesh(); ``` ### Bounding Box Computation Every `Entity` subclass exposes a `GetBoundingBox()` method that returns the axis-aligned bounding box of the geometry. The `BoundingBox` struct provides `Minimum` and `Maximum` corner vectors, useful for spatial queries and camera framing. ```csharp using Aspose.ThreeD.Entities; using Aspose.ThreeD.Utilities; var box = new Box(4, 2, 6); BoundingBox bounds = box.GetBoundingBox(); Vector3 min = bounds.Minimum; Vector3 max = bounds.Maximum; ``` --- ## Quick Start Install the package from NuGet: Load a file, triangulate every mesh, and save the result: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Entities; // Load a scene from an OBJ file var scene = new Scene(); scene.Open("input.obj"); // Walk child nodes and triangulate each mesh entity foreach (var node in scene.RootNode.ChildNodes) { foreach (var entity in node.Entities) { if (entity is Mesh mesh) { mesh.Triangulate(); } } } // Save the triangulated scene as glTF scene.Save("output.glb"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Collada | .dae | Yes | Yes | | FBX | .fbx | Yes | Yes | | glTF / GLB | .gltf / .glb | Yes | Yes | | 3MF | .3mf | Yes | Yes | | Wavefront OBJ | .obj | Yes | Yes | | PLY | .ply | Yes | No | | STL | .stl | Yes | Yes | --- ## Open Source & Licensing Aspose.3D FOSS is released under the MIT license. You can use, modify, and redistribute the library in both open-source and proprietary projects. The full source code is available on GitHub at [aspose-3d-foss/Aspose.3D-FOSS-for-.NET](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-.NET.git). --- ## Getting Started - [Developer Guide](https://docs.aspose.org/3d/net/) -- full documentation covering scene management, format options, and advanced features. - [Knowledge Base](https://kb.aspose.org/3d/net/) -- how-to articles and frequently asked questions. - [API Reference](https://reference.aspose.org/3d/net/) -- class-by-class reference with method signatures and property details. ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Working with 3D File Formats in .NET Using Aspose.3D FOSS URL: https://blog.aspose.org/3d/net/convert-obj-stl-gltf-dotnet/ A practical guide to loading, converting, and saving OBJ, STL, glTF, FBX, and 3MF files in .NET using Aspose.3D FOSS with format-specific options and batch conversion. --- Product: Aspose.3D Platform: net Page Type: index Canonical URL: https://blog.aspose.org/3d/net/convert-obj-stl-gltf-dotnet/ --- # Working with 3D File Formats in .NET Using Aspose.3D FOSS ## Introduction Aspose.3D FOSS for .NET supports key 3D file formats: **OBJ**, **STL**, **glTF**, **FBX**, **Collada**, and **3MF**. This post is a practical, format-by-format guide showing how to load and save each format, what options are available, and how to convert between them. ## Getting Started Install the NuGet package before using any of the examples: All code examples in this guide use the `Aspose.ThreeD` namespace: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Formats; ``` ## OBJ (Wavefront) OBJ is a widely supported text-based format for mesh geometry. Aspose.3D FOSS loads OBJ files along with their companion `.mtl` material files. ### Loading OBJ Open an OBJ file into a new scene and inspect its node hierarchy: ```csharp var scene = new Scene(); scene.Open("model.obj"); Console.WriteLine("Nodes: " + scene.RootNode.ChildNodes.Count); ``` ### Loading with Options Pass an `ObjLoadOptions` instance to customize how the OBJ file is loaded: ```csharp var opts = new ObjLoadOptions(); // Configure loading behavior as needed var scene = new Scene(); scene.Open("model.obj", opts); ``` ### Saving as OBJ Create a scene with geometry and export it as an OBJ file: ```csharp var scene = new Scene(); var box = new Entities.Box(2, 2, 2); scene.RootNode.CreateChildNode("BoxNode", box); scene.Save("output.obj"); ``` ### OBJ with Save Options Use `ObjSaveOptions` to configure the material file name and output options: ```csharp var opts = new ObjSaveOptions(); scene.Save("output.obj", opts); ``` ## STL (Stereolithography) STL is the standard format for 3D printing. It stores raw triangulated geometry without materials or hierarchy. ### Loading STL Open an STL file into a new scene and inspect the loaded geometry: ```csharp var scene = new Scene(); scene.Open("part.stl"); Console.WriteLine("Nodes: " + scene.RootNode.ChildNodes.Count); ``` ### Saving as STL Create a sphere entity and save the scene as an STL file: ```csharp var scene = new Scene(); var sphere = new Entities.Sphere(1); scene.RootNode.CreateChildNode("SphereNode", sphere); scene.Save("output.stl"); ``` ### STL with Save Options Use `StlSaveOptions` to control binary mode, scale, and coordinate flipping: ```csharp var opts = new StlSaveOptions(); // Control binary mode, scale, and coordinate flipping scene.Save("output.stl", opts); ``` ### STL Round-Trip Load an STL file and re-save it to verify that geometry is preserved: ```csharp // Load an STL file and re-save it -- geometry is preserved var scene = new Scene(); scene.Open("original.stl"); scene.Save("copy.stl"); ``` ## glTF 2.0 and GLB glTF is the modern standard for web and real-time 3D. It supports PBR materials, full scene hierarchies, and efficient binary packing (GLB). ### Loading glTF Open a glTF file into a new scene for inspection or processing: ```csharp var scene = new Scene(); scene.Open("model.gltf"); ``` ### Loading with Options Pass a `GltfLoadOptions` instance to customize how the glTF file is imported: ```csharp var opts = new GltfLoadOptions(); var scene = new Scene(); scene.Open("model.gltf", opts); ``` ### Saving as glTF Create a scene and export it as a glTF file: ```csharp var scene = new Scene(); var box = new Entities.Box(2, 2, 2); scene.RootNode.CreateChildNode("BoxNode", box); scene.Save("output.gltf"); ``` ### Saving as GLB (Binary glTF) To produce a self-contained binary `.glb` file, save with a `.glb` extension. The library infers the binary glTF format from the extension: ```csharp scene.Save("output.glb"); ``` ## FBX (Filmbox) FBX is widely used in game development and digital content creation. Aspose.3D FOSS for .NET supports FBX import and export. The `FbxSaveOptions` class provides format-specific save settings. ### Loading FBX Open an FBX file into a new scene for inspection or processing: ```csharp var scene = new Scene(); scene.Open("model.fbx"); ``` ### Loading with Options Pass an `FbxLoadOptions` instance to customize how the FBX file is imported: ```csharp var opts = new FbxLoadOptions(); var scene = new Scene(); scene.Open("model.fbx", opts); ``` ### Saving as FBX Create a scene and export it as an FBX file: ```csharp var scene = new Scene(); var box = new Entities.Box(2, 2, 2); scene.RootNode.CreateChildNode("BoxNode", box); // FBX export always produces binary FBX output scene.Save("output.fbx"); ``` ### Saving with Options Use `FbxSaveOptions` to pass format-specific settings to the FBX writer: ```csharp // Use FbxSaveOptions for format-specific defaults var opts = new FbxSaveOptions(FileContentType.Binary); scene.Save("output.fbx", opts); ``` ## 3MF (3D Manufacturing Format) 3MF is a modern 3D printing format developed by the 3MF Consortium. It supports rich metadata, materials, and multi-object scenes in a single package. ### Loading 3MF Open a 3MF file into a new scene for inspection or processing: ```csharp var scene = new Scene(); scene.Open("model.3mf"); ``` ### Saving as 3MF Create a scene and export it as a 3MF file: ```csharp var scene = new Scene(); var box = new Entities.Box(2, 2, 2); scene.RootNode.CreateChildNode("BoxNode", box); scene.Save("output.3mf"); ``` ### Saving with Options Use `Microsoft3MFSaveOptions` to pass format-specific settings to the 3MF writer: ```csharp var opts = new Microsoft3MFSaveOptions(); scene.Save("output.3mf", opts); ``` ## Stream-Based I/O Formats support loading from and saving to streams, which is useful for web services and cloud processing: ```csharp using var stream = File.OpenRead("model.obj"); var scene = new Scene(); var opts = new ObjLoadOptions(); scene.Open(stream, opts); // Save to a memory stream using var output = new MemoryStream(); var saveOpts = new GltfSaveOptions(FileContentType.Binary); scene.Save(output, saveOpts); ``` ## Format Detection The library can auto-detect formats from file extensions or stream content: ```csharp // Auto-detect from extension var scene = new Scene(); scene.Open("model.obj"); // Detects OBJ from .obj extension // Auto-detect from stream content using var stream = File.OpenRead("model.obj"); scene.Open(stream); // Inspects stream content to determine format ``` ## Batch Conversion For converting multiple files, iterate over a directory and convert each file: ```csharp using Aspose.ThreeD; using Aspose.ThreeD.Formats; var inputDir = "assets/"; var outputDir = "converted/"; foreach (var file in Directory.GetFiles(inputDir, "*.fbx")) { var scene = new Scene(); scene.Open(file); var outputPath = Path.Combine(outputDir, Path.GetFileNameWithoutExtension(file) + ".glb"); scene.Save(outputPath); Console.WriteLine("Converted: " + file); } ``` ## Format Comparison | Feature | OBJ | STL | glTF | FBX | 3MF | |---|---|---|---|---|---| | Materials | MTL | No | PBR | Yes | Yes | | Scene hierarchy | No | No | Yes | Yes | Yes | | Animation stubs | No | No | Yes | Yes | No | | Binary mode | No | Yes | Binary | Yes | Yes | | 3D printing ready | Limited | Yes | No | No | Yes | | Web delivery | No | No | Yes | No | No | ## Summary Aspose.3D FOSS for .NET gives you a single, consistent API for working with all major 3D file formats. The pattern is always the same: create a `Scene`, call `Open()` to load, optionally configure format-specific options, and call `Save()` to export. Format detection, stream-based I/O, and batch conversion make it straightforward to integrate into any .NET pipeline. For more information: - [API Reference](https://reference.aspose.org/3d/net/) -- detailed class and method documentation. - [Knowledge Base](https://kb.aspose.org/3d/net/) -- practical how-to articles. - [GitHub](https://github.com/aspose-3d-foss/Aspose.3D-FOSS-for-NET) -- source code and issue tracker. ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Scene Entities In Net -- Aspose.3D FOSS for .NET URL: https://blog.aspose.org/3d/net/scene-entities-in-net/ Deep dive into scene entities in net with Aspose.3D FOSS for .NET. --- Product: Aspose.3D Platform: net Page Type: index Canonical URL: https://blog.aspose.org/3d/net/scene-entities-in-net/ --- # Scene Entities In Net -- Aspose.3D FOSS for .NET Aspose.3D FOSS for .NET provides powerful capabilities for working with scene entities in net. ## Overview The key classes for this feature area include: - **`Scene`** ## Getting Started Install the package: ## Key Capabilities Aspose.3D FOSS for .NET lets you work with scene entities in net programmatically without external dependencies. ## Learn More - [Developer Guide](https://docs.aspose.org/3d/net/developer-guide/) - [API Reference](https://reference.aspose.org/3d/net/) - [Knowledge Base](https://kb.aspose.org/3d/net/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.3D FOSS for Python URL: https://blog.aspose.org/3d/python/ --- Product: Aspose.3D Platform: python Page Type: index Canonical URL: https://blog.aspose.org/3d/python/ --- # Aspose.3D FOSS for Python ## Related Resources - [Aspose.3D for Python — Enterprise Product](https://products.aspose.com/3d/python-net/) ## Related Topics - [Create Keyframe Animations and Work with 3D Formats Using Aspose.3D FOSS](https://blog.aspose.org/3d/python/3d-python-keyframe-animation/) - [Introducing Aspose.3D FOSS for Python](https://blog.aspose.org/3d/python/3d-python-obj-stl-gltf-convert/) - [Scene Management In Python -- Aspose.3D FOSS for Python](https://blog.aspose.org/3d/python/3d-python-scene-nodes-hierarchy/) - [Key Features of Aspose.3D FOSS for Python](https://blog.aspose.org/3d/python/aspose-3d-foss-for-python-key-features/) - [Practical Guide: Converting Between 3D Formats in Python](https://blog.aspose.org/3d/python/convert-obj-stl-gltf-python/) --- # Create Keyframe Animations and Work with 3D Formats Using Aspose.3D FOSS URL: https://blog.aspose.org/3d/python/3d-python-keyframe-animation/ These capabilities are essential for spatial reasoning, collision detection, and `scene` layout in 3D python game engines and visualization tools. --- Product: Aspose.3D Platform: python Page Type: index Canonical URL: https://blog.aspose.org/3d/python/3d-python-keyframe-animation/ --- # Create Keyframe Animations and Work with 3D Formats Using Aspose.3D FOSS ## Introduction This post highlights the key features of `aspose-3d-foss` for Python — a FOSS library for loading, exporting, and traversing 3D scenes in Python. The library provides a `Scene` hierarchy with `Node`, `Mesh`, `Camera`, and `Light` objects, format-specific I/O for OBJ, STL, and glTF, and inspection of keyframe animation data. Developers can compute axis-aligned bounding boxes to determine object extents and optimize rendering pipelines. Transformations (including `translation`, `rotation`, and `scaling`) allow precise control over `entity` placement within a `scene`. For interoperability, Aspose.3D provides native support for the **STL** (Stereo Lithography) format, widely used in 3D printing and CAD workflows. ## Quick Start Install the package from PyPI and import the core classes: ## Key Highlights - Support for `Camera` and `Light` objects enables realistic scene lighting and view configuration in 3D visualizations and game development - Animation inspection via `AnimationClip`, `AnimationNode`, and `KeyframeSequence` classes with interpolation modes including `LINEAR`, `BEZIER`, `B_SPLINE`, and `CARDINAL_SPLINE` - Precise control over animation extrapolation using `Extrapolation` and `ExtrapolationType` ensures consistent behavior beyond keyframe ranges - Native support for the **3MF** (3D Manufacturing Format) via `FileFormat.MICROSOFT_3MF_FORMAT` streamlines 3D printing and manufacturing pipelines - Hierarchical scene graph with `Node`, `Entity`, and `A3DObject` classes for attaching meshes, cameras, and lights to the scene tree ```python from aspose.threed.entities import Camera # Create a Camera instance cam = Camera("main") # Access the name property print(cam.name) # "main" ``` ## Getting Started Use `Scene`, `Mesh`, and `Node` to build a 3D scene programmatically in Python, including polygon mesh building, `material` assignment for OBJ files, and export to multiple formats. The following example creates a triangular mesh and attaches it to the scene root node: ```python from aspose.threed import Scene from aspose.threed.entities import Mesh # Create a scene, attach a mesh, and inspect it scene = Scene() mesh = Mesh("triangle") mesh.create_polygon(0, 1, 2) node = scene.root_node.create_child_node("Shape", mesh) print(node.name) # "Shape" print(mesh.polygon_count) # 1 ``` ## See Also Explore related capabilities in Aspose.3D for Python, including mesh manipulation, scene graph traversal, and export to glTF and OBJ formats. - [Learn about bounding box calculations](/3d/python/3d-python-obj-stl-gltf-convert/) - [Streamline 3D printing imports](https://docs.aspose.org/3d/python/developer-guide/model-loading/) - [Optimize 3D printing workflows](https://docs.aspose.org/3d/python/developer-guide/rendering/) - [Convert 3D models with Python](https://kb.aspose.org/3d/python/how-to-convert-3d-models-in-python/) - [Fix 3D model errors in Python](https://kb.aspose.org/3d/python/how-to-fix-3d-models-errors-python/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) - [Aspose.3D for Python — Enterprise Product](https://products.aspose.com/3d/python-net/) --- # Introducing Aspose.3D FOSS for Python URL: https://blog.aspose.org/3d/python/3d-python-obj-stl-gltf-convert/ Aspose.3D FOSS for Python is a zero-dependency, MIT-licensed library for loading and converting OBJ, STL, glTF, COLLADA, and 3MF files in pure Python. --- Product: Aspose.3D Platform: python Page Type: index Canonical URL: https://blog.aspose.org/3d/python/3d-python-obj-stl-gltf-convert/ --- # Introducing Aspose.3D FOSS for Python ## Introduction We are releasing **Aspose.3D FOSS for Python**, a pure-Python library for reading, writing, and converting common 3D file formats. The library is published on PyPI as [`aspose-3d-foss`](https://pypi.org/project/aspose-3d-foss/), carries an MIT license, and has zero external dependencies. If you have ever needed to inspect or convert 3D files programmatically (extract mesh vertex counts, pipe OBJ geometry into a processing script, or batch-convert STL files to glTF for a web viewer), this library is built for that use case. It does not require a graphics driver, a native extension module, or any cloud connection. --- ## What's Included ### Core Scene Graph Every file is loaded into a `Scene` object that mirrors the original file's node hierarchy. Nodes carry `Transform` (translation, rotation, scale) and one or more attached entities such as `Mesh`, `Camera`, or `Light`. The scene graph is the same regardless of source format, so code written to walk and process geometry works across all supported formats without modification. ### Geometry Access `Mesh` objects expose: - `control_points`: list of vertex positions as `Vector4` (x, y, z, w) - `polygons`: list of face index lists (arbitrary polygon arity, not just triangles) - `get_element(VertexElementType)`: retrieves named vertex data layers for normals, UVs, vertex colours, and smoothing groups ### Materials `LambertMaterial` and `PhongMaterial` carry the material properties read from OBJ `.mtl` files (ambient, diffuse, specular, emissive, transparency, shininess). Materials survive the load–save round trip for formats that support them. ### Math Utilities `Vector2`, `Vector3`, `Vector4`, `FVector3`, `Quaternion`, `Matrix4`, and `BoundingBox` are included as lightweight value types for geometry calculations. ### Animation The `AnimationClip`, `AnimationNode`, `KeyframeSequence`, and `KeyFrame` classes provide access to keyframe animation data from formats that carry it, such as glTF and COLLADA. --- ## Quick Start Load a 3D file and print the vertex count of every mesh: ```python from aspose.threed import Scene from aspose.threed.entities import Mesh scene = Scene.from_file("model.obj") def visit(node): for entity in node.entities: if isinstance(entity, Mesh): print(f"{node.name}: {len(entity.control_points)} vertices, " f"{len(entity.polygons)} polygons") for child in node.child_nodes: visit(child) visit(scene.root_node) ``` Convert the same file to glTF: ```python from aspose.threed import Scene from aspose.threed.formats import GltfSaveOptions scene = Scene.from_file("model.obj") scene.save("model.gltf", GltfSaveOptions()) ``` That is the complete program. No configuration files, no API keys, no network calls. --- ## Supported Formats | Format | Extension(s) | Load | Save | Notes | |---|---|:---:|:---:|---| | OBJ | `.obj` | Yes | Yes | `.mtl` material loading supported | | STL | `.stl` | Yes | Yes | Binary and ASCII; coordinate-system flip option | | glTF | `.gltf`, `.glb` | Yes | Yes | `.glb` (self-contained binary) supported | | COLLADA | `.dae` | Yes | Yes | `ColladaSaveOptions` available with `flip_coordinate_system`, `enable_materials`, `indented` | | 3MF | `.3mf` | Yes | Yes | Suitable for 3D printing workflows | | FBX | `.fbx` | Partial | N/A | Tokenizer only; full parser in progress | Format detection is automatic from the file extension. Format-specific load and save options (`ObjLoadOptions`, `StlSaveOptions`, `GltfSaveOptions`, `ThreeMfSaveOptions`) are available for fine-grained control. --- ## Getting Started - **Install**: See the [Installation guide](https://docs.aspose.org/3d/python/getting-started/installation/) - **How-to: Loading files**: [How to Load 3D Models in Python](https://kb.aspose.org/3d/python/how-to-load-3d-models-in-python/) - **How-to: Converting files**: [How to Convert 3D Models in Python](https://kb.aspose.org/3d/python/how-to-convert-3d-models-in-python/) - **API Reference**: [Aspose.3D FOSS for Python API Reference](https://reference.aspose.org/3d/python/) - **PyPI**: [aspose-3d-foss on PyPI](https://pypi.org/project/aspose-3d-foss/) --- ## Conclusion Aspose.3D FOSS for Python 26.1.0 covers the most common 3D file formats used in tooling, pipelines, and web applications (OBJ, STL, glTF, COLLADA, and 3MF) with a consistent Python API and no installation friction. If you encounter a bug, an unsupported edge case, or a format you need added, please open an issue on GitHub. We actively maintain the library and welcome contributions. ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Scene Management In Python -- Aspose.3D FOSS for Python URL: https://blog.aspose.org/3d/python/3d-python-scene-nodes-hierarchy/ Deep dive into scene management in python with Aspose.3D FOSS for Python. --- Product: Aspose.3D Platform: python Page Type: index Canonical URL: https://blog.aspose.org/3d/python/3d-python-scene-nodes-hierarchy/ --- # Scene Management In Python -- Aspose.3D FOSS for Python Aspose.3D FOSS for Python provides powerful capabilities for working with scene management in python. ## Overview The key classes for this feature area include: - **`Scene`** ## Getting Started Install the package: ## Key Capabilities Aspose.3D FOSS for Python lets you work with scene management in python programmatically without external dependencies. ## Learn More - [Developer Guide](https://docs.aspose.org/3d/python/developer-guide/) - [API Reference](https://reference.aspose.org/3d/python/) - [Knowledge Base](https://kb.aspose.org/3d/python/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Key Features of Aspose.3D FOSS for Python URL: https://blog.aspose.org/3d/python/aspose-3d-foss-for-python-key-features/ Aspose.3D FOSS for Python provides a hierarchical scene graph (Scene, Node, Mesh), bounding-box and transform math, and keyframe animation support for 3D game engines and visualization tools. --- Product: Aspose.3D Platform: python Page Type: index Canonical URL: https://blog.aspose.org/3d/python/aspose-3d-foss-for-python-key-features/ --- # Key Features of Aspose.3D FOSS for Python Aspose.3D enables robust manipulation of 3D content in Python applications, with core support for bounding boxes and transformations. These capabilities are essential for spatial reasoning, collision detection, and `scene` layout in 3D visualization tools and game engines. Developers can compute axis-aligned bounding boxes to determine object extents and optimize rendering pipelines. Transformations (including `translation`, `rotation`, and `scaling`) allow precise control over `entity` placement within a `scene`, supporting workflows in 3D visualization and game development. The `library` also supports keyframe animation sequences, enabling smooth `interpolation` of transformations over `time`. For interoperability, Aspose.3D provides native support for the **STL** (Stereo Lithography) format, widely used in 3D printing and CAD workflows. ## Key Highlights - Support for `Camera` and `Light` objects enables realistic scene lighting and view configuration in 3D visualizations and game development - Animation inspection via `AnimationClip`, `AnimationNode`, and `KeyframeSequence` classes with interpolation modes including `LINEAR`, `BEZIER`, `B_SPLINE`, and `CARDINAL_SPLINE` - Precise control over animation extrapolation using `Extrapolation` and `ExtrapolationType` ensures consistent behavior beyond keyframe ranges - Native support for the **3MF** (3D Manufacturing Format) via `FileFormat.MICROSOFT_3MF_FORMAT` streamlines 3D printing and manufacturing pipelines - Hierarchical scene graph with `Scene` and `Node` provides structured organization for transformations, bounding boxes, and rendering Every scene is a tree rooted at `Scene.root_node`. Build the hierarchy with `Node.add_child_node()`, attach a `Mesh` (or other entity) to a node through `Node.entity`, and walk the tree via `Node.child_nodes`: ```python from aspose.threed import Scene from aspose.threed.entities import Node, Mesh scene = Scene() group = Node("Group") scene.root_node.add_child_node(group) cube_node = Node("Cube") cube_node.entity = Mesh("Cube") group.add_child_node(cube_node) for child in scene.root_node.child_nodes: print(f"{child.name}: {len(child.child_nodes)} children") ``` ## Getting Started Aspose.3D enables robust 3D processing in Python, supporting triangulation for polygon conversion, full `material` handling for OBJ files, and ongoing expansion to additional `formats`. Developers building 3D game engines, visualization tools, or games can integrate these capabilities with minimal setup. ```python from aspose.threed import Scene from aspose.threed.entities import Mesh from aspose.threed.utilities import Vector4 # Create a simple scene with a mesh # Note: control_points returns a copy — use _control_points to add vertices scene = Scene() mesh = Mesh("cube") mesh._control_points.append(Vector4(0, 0, 0, 1)) mesh._control_points.append(Vector4(1, 0, 0, 1)) mesh._control_points.append(Vector4(0.5, 1, 0, 1)) mesh.create_polygon(0, 1, 2) node = scene.root_node.create_child_node("Cube", mesh) print(node.name) # "Cube" ``` ## See Also Explore related capabilities in Aspose.3D for Python, including mesh manipulation and modification, and support for industry-standard `formats` like GLTF and OBJ. These features enable robust 3D game development, visualization, and integration into game engines. - [Learn about bounding box calculations](/3d/python/3d-python-obj-stl-gltf-convert/) - [Streamline 3D printing imports](https://docs.aspose.org/3d/python/developer-guide/model-loading/) - [Optimize 3D printing workflows](https://docs.aspose.org/3d/python/developer-guide/rendering/) - [Convert 3D models with Python](https://kb.aspose.org/3d/python/how-to-convert-3d-models-in-python/) - [Fix 3D model errors in Python](https://kb.aspose.org/3d/python/how-to-fix-3d-models-errors-python/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) - [Aspose.3D for Python — Enterprise Product](https://products.aspose.com/3d/python-net/) --- # Practical Guide: Converting Between 3D Formats in Python URL: https://blog.aspose.org/3d/python/convert-obj-stl-gltf-python/ Step-by-step guide to converting OBJ, STL, glTF, and 3MF files in Python using Aspose.3D FOSS. Includes batch conversion patterns and format-specific save options. --- Product: Aspose.3D Platform: python Page Type: index Canonical URL: https://blog.aspose.org/3d/python/convert-obj-stl-gltf-python/ --- # Practical Guide: Converting Between 3D Formats in Python ## Introduction 3D content rarely stays in a single format for its entire lifetime. A model may originate as an OBJ file exported from a modelling application, travel through a 3D printing pipeline as STL, appear in a web application as glTF, and end up in an additive manufacturing tool as 3MF. Each format serves a different audience and a different downstream tool, and conversion between them is something most 3D pipelines need to handle reliably. Python is a natural fit for this work: shell scripts are too fragile, and full DCC (digital content creation) tool integrations are too heavy for batch processing. What you need is a library that can load any of these formats, give you a consistent scene graph, and write back out to any target format without requiring a GUI or a graphics driver. Aspose.3D FOSS for Python (`aspose-3d-foss`, MIT license) covers that gap. This guide shows the most common conversion paths with complete, runnable code examples. --- ## Which Formats Does Aspose.3D FOSS Support? | Format | Extension(s) | Load | Save | Common Use Case | |---|---|:---:|:---:|---| | OBJ | `.obj` | Yes | Yes | Interchange from modelling tools; `.mtl` material files supported | | STL | `.stl` | Yes | Yes | 3D printing, CAD export; binary and ASCII variants | | glTF | `.gltf`, `.glb` | Yes | Yes | Web viewers, game engines; `.glb` is the self-contained binary variant | | COLLADA | `.dae` | Yes | Yes | Import from animation tools; `ColladaSaveOptions` supports export | | 3MF | `.3mf` | Yes | Yes | Additive manufacturing, richer print metadata than STL | Format detection is automatic from the file extension. Format-specific option classes (`ObjLoadOptions`, `StlSaveOptions`, `GltfSaveOptions`) are available when you need fine-grained control. > **Note on FBX:** The library includes a partial FBX tokenizer for import. FBX is not recommended for production conversion workflows in this release; use OBJ or glTF as intermediate formats instead. --- ## OBJ to STL: Preparing a Model for 3D Printing OBJ is the most common output format from modelling and sculpting tools. STL is the lingua franca of 3D printing slicers. Converting between them is a single call. ```python from aspose.threed import Scene from aspose.threed.formats import StlSaveOptions scene = Scene.from_file("model.obj") opts = StlSaveOptions() scene.save("model.stl", opts) ``` STL only encodes triangle faces. If your OBJ file contains quad or n-gon faces, the exporter triangulates them automatically before writing. If you want to control the triangulation explicitly before saving, call `mesh.triangulate()` on each mesh in the scene: ```python from aspose.threed import Scene from aspose.threed.entities import Mesh from aspose.threed.formats import StlSaveOptions scene = Scene.from_file("model.obj") def triangulate_all(node): if isinstance(node.entity, Mesh): # entity setter clears existing entities and sets the new one node.entity = node.entity.triangulate() for child in node.child_nodes: triangulate_all(child) triangulate_all(scene.root_node) scene.save("model_triangulated.stl", StlSaveOptions()) ``` --- ## OBJ to glTF: Exporting for Web and Game Engines glTF 2.0 is the preferred interchange format for real-time renderers, WebGL viewers, and game engines such as Babylon.js, Three.js, and Unity. GLB (the binary variant) packages geometry, textures, and materials into a single self-contained file, which is easier to serve over HTTP. ```python from aspose.threed import Scene from aspose.threed.formats import GltfSaveOptions scene = Scene.from_file("model.obj") ##Save as JSON-based glTF (external buffer) opts_gltf = GltfSaveOptions() scene.save("model.gltf", opts_gltf) ##Save as self-contained GLB binary: preferred for web delivery scene.save("model.glb", GltfSaveOptions()) ``` The format is inferred from the file extension: `.gltf` produces the JSON+binary-buffer pair; `.glb` produces the single-file binary. OBJ material data (`LambertMaterial`, `PhongMaterial`) is carried through to the glTF PBR material representation where an equivalent exists. --- ## STL to glTF: From Scanner or CAD Output to Web STL files from 3D scanners and CAD systems are common inputs that need to be made web-viewable. STL carries only triangle geometry and no material data, so the conversion is straightforward. ```python from aspose.threed import Scene from aspose.threed.formats import GltfSaveOptions scene = Scene.from_file("scan.stl") scene.save("scan.glb", GltfSaveOptions()) ``` If the STL was produced by a CAD tool with an unusual coordinate system (Z-up vs Y-up), you can inspect and correct the root node transform before saving: ```python import math from aspose.threed import Scene from aspose.threed.formats import GltfSaveOptions scene = Scene.from_file("cad_export.stl") # Rotate -90 degrees around X to convert Z-up to Y-up # set_euler_angles takes radians, not degrees root = scene.root_node root.transform.set_euler_angles(-math.pi / 2, 0.0, 0.0) scene.save("cad_export_yup.glb", GltfSaveOptions()) ``` --- ## glTF to 3MF: Preparing for Additive Manufacturing 3MF is a modern 3D printing format backed by the 3MF Consortium. It supports richer metadata than STL (colour, material assignments, build instructions) and is accepted by slicer software such as PrusaSlicer and Bambu Studio. If you are delivering models from a web viewer into a printing workflow, converting GLB to 3MF is a useful step. ```python from aspose.threed import Scene from aspose.threed import FileFormat from aspose.threed.formats import SaveOptions scene = Scene.from_file("model.glb") scene.save("model.3mf") ``` The 3MF format is detected automatically from the `.3mf` extension. For explicit control, pass a `SaveOptions` instance configured for 3MF. --- ## Batch Conversion Pattern In practice, conversion tasks operate on directories of files rather than individual files. The following pattern handles a folder of OBJ files and converts each one to GLB, with per-file error handling so a single bad file does not abort the entire run. ```python import os from aspose.threed import Scene from aspose.threed.formats import GltfSaveOptions input_dir = "./obj_files" output_dir = "./glb_files" os.makedirs(output_dir, exist_ok=True) opts = GltfSaveOptions() results = {"ok": [], "failed": []} for filename in os.listdir(input_dir): if not filename.lower().endswith(".obj"): continue src = os.path.join(input_dir, filename) stem = os.path.splitext(filename)[0] dst = os.path.join(output_dir, stem + ".glb") try: scene = Scene.from_file(src) scene.save(dst, opts) results["ok"].append(filename) print(f"OK {filename} -> {stem}.glb") except Exception as exc: results["failed"].append((filename, str(exc))) print(f"ERR {filename}: {exc}") print(f"\n{len(results['ok'])} converted, {len(results['failed'])} failed.") if results["failed"]: for name, reason in results["failed"]: print(f" {name}: {reason}") ``` This pattern extends naturally to other source/target format pairs: change the extension filter and the `SaveOptions` class for any combination in the support table above. --- ## Conclusion Aspose.3D FOSS for Python makes format conversion straightforward: load with `Scene.from_file`, optionally inspect or modify the scene graph, then save with the appropriate `SaveOptions`. The library handles triangulation, coordinate normalization, and format-specific quirks internally. For a full list of classes and methods, see the [API Reference](https://reference.aspose.org/3d/python/). To go deeper on the scene graph model (nodes, meshes, transforms), see: - [Class Scene](https://reference.aspose.org/3d/python/scene/): loading, saving, and scene-level metadata - [Class Node](https://reference.aspose.org/3d/python/node/): hierarchy, transforms, entity attachment - [Class Mesh](https://reference.aspose.org/3d/python/mesh/): vertex data, polygons, vertex elements - [How to Load 3D Models in Python](https://kb.aspose.org/3d/python/how-to-load-3d-models-in-python/) - [PyPI: aspose-3d-foss](https://pypi.org/project/aspose-3d-foss/) ## Getting Started - [Getting Started](https://docs.aspose.org/3d/python/getting-started/) - [Developer Guide](https://docs.aspose.org/3d/python/developer-guide/) - [KB Articles](https://kb.aspose.org/3d/python/) - [API Reference](https://reference.aspose.org/3d/python/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.3D FOSS for TypeScript URL: https://blog.aspose.org/3d/typescript/ --- Product: Aspose.3D Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/3d/typescript/ --- # Aspose.3D FOSS for TypeScript ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) ## Related Topics - [Introducing Aspose.3D FOSS for TypeScript](https://blog.aspose.org/3d/typescript/3d-typescript-gltf-fbx-convert/) - [Bring 3D Scenes to Life with Aspose.3D FOSS for TypeScript Keyframe Animation](https://blog.aspose.org/3d/typescript/3d-typescript-keyframe-scene/) - [Key Features of Aspose.3D FOSS for TypeScript](https://blog.aspose.org/3d/typescript/aspose-3d-foss-for-typescript-key-features/) - [Converting Between 3D Formats in TypeScript with Aspose.3D FOSS](https://blog.aspose.org/3d/typescript/convert-obj-gltf-fbx-typescript/) --- # Introducing Aspose.3D FOSS for TypeScript URL: https://blog.aspose.org/3d/typescript/3d-typescript-gltf-fbx-convert/ Aspose.3D FOSS for TypeScript is now available on npm. Load, convert, and export OBJ, glTF, GLB, STL, 3MF, FBX, and COLLADA files in Node.js with full TypeScript type definitions. --- Product: Aspose.3D Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/3d/typescript/3d-typescript-gltf-fbx-convert/ --- # Introducing Aspose.3D FOSS for TypeScript ## Introduction We are pleased to announce **Aspose.3D FOSS for TypeScript**, which ships as the `@aspose/3d` package built from source today. This MIT-licensed library brings production-quality 3D scene processing to TypeScript and Node.js applications without requiring native binaries, platform-specific toolchains, or commercial licenses. The library is designed around a straightforward `Scene` API: load a 3D file with `scene.open()`, inspect or transform the scene graph, and write the result with `scene.save()`. Full TypeScript type definitions are bundled; no separate `@types/` package is required. ## Key Features **Multi-format I/O.** The package reads and writes OBJ, glTF 2.0, GLB, STL, 3MF, and COLLADA files in a single install. FBX format classes are included but require explicit format registration; use OBJ, glTF, or STL for file conversion workflows. **First-class TypeScript support.** All public classes, enumerations, and option types are fully typed. IDEs with TypeScript language service support (VS Code, WebStorm, etc.) provide TypeScript autocompletion for all API calls without a separate `@types/` package. **Node.js 18–22+ compatibility.** The package is tested against Node.js 18, 20, and 22 LTS releases. No native addons are compiled during install, so it works on Linux, macOS, and Windows. **One runtime dependency.** The only dependency is `xmldom`, used exclusively for COLLADA XML parsing. All other format parsers are pure JavaScript implementations. **MIT license.** Use `@aspose/3d` in commercial, open-source, or internal projects without restriction. ## Quick Start Build the `@aspose/3d` package from source: Load an OBJ file and convert it to a binary GLB: ```typescript import { Scene } from '@aspose/3d'; import { ObjLoadOptions } from '@aspose/3d/formats/obj'; import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf'; const scene = new Scene(); scene.open('model.obj', new ObjLoadOptions()); const saveOpts = new GltfSaveOptions(); saveOpts.binaryMode = true; // produce a single .glb file scene.save('output.glb', GltfFormat.getInstance(), saveOpts); console.log('Converted to GLB successfully'); ``` Iterate over scene nodes to inspect geometry: ```typescript import { Scene } from '@aspose/3d'; import { ObjLoadOptions } from '@aspose/3d/formats/obj'; const scene = new Scene(); scene.open('model.obj', new ObjLoadOptions()); for (const node of scene.rootNode.childNodes) { console.log(`Node: ${node.name}`); if (node.entity) { console.log(` Entity type: ${node.entity.constructor.name}`); } } ``` ## Supported Formats | Format | Extension | Import | Export | Notes | |---|---|:---:|:---:|---| | OBJ | `.obj` | Yes | Yes | Wavefront OBJ; reads/writes `.mtl` material files | | glTF | `.gltf` / `.glb` | Yes | Yes | glTF 2.0 JSON and GLB binary | | STL | `.stl` | Yes | Yes | ASCII and binary STL | | 3MF | `.3mf` | Yes | Yes | Open Packaging Convention archive | | FBX | `.fbx` | No* | No* | Importer/exporter exist but format auto-detection not wired | | COLLADA | `.dae` | Yes | Yes | Requires bundled `xmldom` dependency | ## TypeScript Advantages Working with `@aspose/3d` in TypeScript catches category errors at compile time rather than at runtime. When you call `scene.save()`, the compiler verifies that the options object matches the expected `SaveOptions` subtype for the chosen format. Format-specific load and save options expose only the properties relevant to that format; there is no untyped options bag to guess at. For example, `GltfSaveOptions.binaryMode` is a typed `boolean`, so the compiler rejects `saveOpts.binaryMode = 'yes'` before any code runs. Animation properties on `AnimationClip`, material channels on `PbrMaterial`, and vertex element types on `VertexElement` are all similarly typed and discoverable through IntelliSense without consulting external documentation. ## Open Source The package is published under the **MIT License**. Source code is available on GitHub. Contributions, bug reports, and format support requests are welcome through the repository's issue tracker. The library has one runtime dependency: `xmldom` (`^0.6.0`), used only when reading or writing COLLADA files. All other parsers and writers are self-contained pure-JavaScript implementations with no binary components. ## Getting Started - **Build from source**: See the [Installation guide](https://docs.aspose.org/3d/typescript/getting-started/installation/) - **Knowledge Base**: [How to Load 3D Models in TypeScript](https://kb.aspose.org/3d/typescript/how-to-load-3d-models-in-typescript/) - **Knowledge Base**: [How to Export 3D Scenes to glTF/GLB in TypeScript](https://kb.aspose.org/3d/typescript/how-to-export-gltf-in-typescript/) - **API Reference**: [Aspose.3D FOSS for TypeScript: Full Class Reference](/3d/typescript/) - **GitHub**: [aspose-3d/aspose-3d-node](https://github.com/aspose-3d/aspose-3d-node) ## Conclusion `@aspose/3d` version 24.12.0 provides a stable, typed, dependency-light foundation for 3D file processing in TypeScript and Node.js. Whether the use case is format conversion, scene inspection, geometry extraction, or pipeline integration, the library covers the most common 3D interchange formats under a permissive open-source license. Install it today and let us know what you build. ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Bring 3D Scenes to Life with Aspose.3D FOSS for TypeScript Keyframe Animation URL: https://blog.aspose.org/3d/typescript/3d-typescript-keyframe-scene/ Aspose.3D FOSS for TypeScript provides scene graph management, multi-format I/O, mesh operations, keyframe animation, and PBR material support for Node.js. --- Product: Aspose.3D Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/3d/typescript/3d-typescript-keyframe-scene/ --- # Bring 3D Scenes to Life with Aspose.3D FOSS for TypeScript Keyframe Animation ## Introduction Aspose.3D FOSS for TypeScript (`@aspose/3d`) is an open-source, MIT-licensed 3D file format library primarily designed for Node.js. Developers building 3D model viewers, format converters, geometry processing tools, or server-side 3D pipelines can install it with a single command (see the [Installation guide](https://docs.aspose.org/3d/typescript/getting-started/installation/)) and immediately start loading, constructing, and exporting 3D content. The library uses `require('fs')` and `Buffer` from Node.js; browser usage requires appropriate shims for those APIs and is not officially supported. The scene graph API mirrors the model familiar from 3D authoring tools: a `Scene` holds a `rootNode`, each `Node` can carry child nodes and entity objects (`Mesh`, `Camera`, `Light`), and the transform hierarchy is fully accessible for reading and writing. ## Key Features - **Multi-format I/O**: Read and write OBJ (with `.mtl` materials), glTF 2.0 / GLB, STL (binary and ASCII), 3MF, and COLLADA from file paths and in-memory `Buffer` objects. - **Scene graph API**: `Scene`, `Node`, `Mesh`, `Camera`, `Light` hierarchy with full parent/child management; traverse nodes recursively via `node.childNodes` - **PBR material system**: Lambert, Phong, and PBR (metallic/roughness) materials accessible via `node.material` - **Mesh operations**: Access raw vertex data via `mesh.controlPoints` (array of `Vector4`), polygon indices via `mesh.polygonCount`, and vertex element channels via `mesh.getElement()` - **Math utilities**: `Vector2`, `Vector3`, `Vector4`, `Matrix4`, `Quaternion`, and bounding box types for spatial calculations - **Animation system**: Keyframe animation with `AnimationClip`, `AnimationChannel`, and interpolation curves (linear, Bezier, TCB spline) - **Format-specific options**: Per-format `LoadOptions` / `SaveOptions` classes control coordinate flipping, scale, material loading, and more ## Quick Start Build the package from source. Node.js 18 or later is required; TypeScript 5.0+ is recommended. Load an OBJ file and inspect the scene: ```typescript import { Scene } from '@aspose/3d'; import { ObjLoadOptions } from '@aspose/3d/formats/obj'; const scene = new Scene(); const options = new ObjLoadOptions(); options.enableMaterials = true; scene.open('model.obj', options); for (const node of scene.rootNode.childNodes) { if (node.entity && 'controlPoints' in node.entity) { const mesh = node.entity as any; console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices`); } } ``` ## Export to glTF Save any loaded or constructed scene to glTF 2.0 binary (GLB): ```typescript import { Scene } from '@aspose/3d'; import { ObjLoadOptions } from '@aspose/3d/formats/obj'; const scene = new Scene(); scene.open('input.obj', new ObjLoadOptions()); scene.save('output.glb'); console.log('Exported to output.glb'); ``` The library auto-detects the output format from the file extension. Pass a `GltfSaveOptions` instance for control over PBR material embedding, textures, and binary vs. JSON encoding. ## Scene Construction The following example builds a scene programmatically from a `Mesh` and exports it to GLB format: ```typescript import { Scene, Node } from '@aspose/3d'; import { Mesh } from '@aspose/3d/entities'; const scene = new Scene(); const mesh = new Mesh(); // ... populate mesh.controlPoints and polygons ... const node = new Node('myMesh'); node.entity = mesh; scene.rootNode.addChildNode(node); scene.save('programmatic.glb'); ``` ## Getting Started Build `@aspose/3d` from source and run any of the examples above. For a step-by-step guide covering installation, loading, converting, and saving 3D files in TypeScript, see the [Getting Started](https://docs.aspose.org/3d/typescript/getting-started/) section of the documentation. ## See Also - [How to Load 3D Models in TypeScript](https://kb.aspose.org/3d/typescript/how-to-load-3d-models-in-typescript/) - [How to Export glTF in TypeScript](https://kb.aspose.org/3d/typescript/how-to-export-gltf-in-typescript/) - [Format Support](https://docs.aspose.org/3d/typescript/developer-guide/format-support/) - [API Reference](https://reference.aspose.org/3d/typescript/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) - [Aspose.3D for TypeScript — Enterprise Product](https://products.aspose.com/3d/typescript/) --- # Key Features of Aspose.3D FOSS for TypeScript URL: https://blog.aspose.org/3d/typescript/aspose-3d-foss-for-typescript-key-features/ Aspose.3D FOSS for TypeScript provides scene graph management, multi-format I/O, mesh operations, keyframe animation, and PBR material support for Node.js. --- Product: Aspose.3D Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/3d/typescript/aspose-3d-foss-for-typescript-key-features/ --- # Key Features of Aspose.3D FOSS for TypeScript ## Introduction Aspose.3D FOSS for TypeScript (`@aspose/3d`) is an open-source, MIT-licensed 3D file format library primarily designed for Node.js. Developers building 3D model viewers, format converters, geometry processing tools, or server-side 3D pipelines can install it with a single command (see the [Installation guide](https://docs.aspose.org/3d/typescript/getting-started/installation/)) and immediately start loading, constructing, and exporting 3D content. The library uses `require('fs')` and `Buffer` from Node.js; browser usage requires appropriate shims for those APIs and is not officially supported. The library supports the major interchange formats — OBJ, glTF 2.0 / GLB, STL, 3MF, and COLLADA for both import and export. FBX importer/exporter classes exist but are not yet wired into format auto-detection. The scene graph API mirrors the model familiar from 3D authoring tools: a `Scene` holds a `rootNode`, each `Node` can carry child nodes and entity objects (`Mesh`, `Camera`, `Light`), and the transform hierarchy is fully accessible for reading and writing. ## Key Features - **Multi-format I/O**: Import and export OBJ (with `.mtl` materials), glTF 2.0 / GLB, STL (binary and ASCII), 3MF, and COLLADA from both file paths and in-memory `Buffer` objects. FBX support is not yet wired into auto-detection. - **Scene graph API**: `Scene`, `Node`, `Mesh`, `Camera`, `Light` hierarchy with full parent/child management; traverse nodes recursively via `node.childNodes` - **PBR material system**: Lambert, Phong, and PBR (metallic/roughness) materials accessible via `node.material` - **Mesh operations**: Access raw vertex data via `mesh.controlPoints` (array of `Vector4`), polygon indices via `mesh.polygonCount`, and vertex element channels via `mesh.getElement()` - **Math utilities**: `Vector2`, `Vector3`, `Vector4`, `Matrix4`, `Quaternion`, and bounding box types for spatial calculations - **Animation system**: Keyframe animation with `AnimationClip`, `AnimationChannel`, and interpolation curves (linear, Bezier, TCB spline) - **Format-specific options**: Per-format `LoadOptions` / `SaveOptions` classes control coordinate flipping, scale, material loading, and more ## Getting Started Build the package from source. Node.js 18 or later is required; TypeScript 5.0+ is recommended. Load an OBJ file and inspect the scene: ```typescript import { Scene } from '@aspose/3d'; import { ObjLoadOptions } from '@aspose/3d/formats/obj'; const scene = new Scene(); const options = new ObjLoadOptions(); options.enableMaterials = true; scene.open('model.obj', options); for (const node of scene.rootNode.childNodes) { if (node.entity && 'controlPoints' in node.entity) { const mesh = node.entity as any; console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices`); } } ``` ## Scene Graph API Every scene is a tree of `Node` objects rooted at `scene.rootNode`. Build the hierarchy with `addChildNode()`, attach entities such as `Camera` or `Light` to a node via its `entity` property, and read each node's local or world-space transform through `transform` and `globalTransform`. ```typescript import { Scene, Node, Camera, Light } from '@aspose/3d'; const scene = new Scene(); const cameraNode = new Node('MainCamera'); cameraNode.entity = new Camera('MainCamera'); scene.rootNode.addChildNode(cameraNode); const lightNode = new Node('KeyLight'); lightNode.entity = new Light('KeyLight'); scene.rootNode.addChildNode(lightNode); for (const child of scene.rootNode.childNodes) { console.log(`${child.name}: ${child.entity?.constructor.name}`); } ``` ## Math Utilities `Vector3`, `Vector4`, `Matrix4`, and `Quaternion` back every geometric operation in the library. `Vector3` and `Vector4` expose `x`/`y`/`z`(/`w`) components plus `length`, `dot()`, and `cross()`; `Matrix4` is a 4×4 grid accessed through `m00`–`m33` with `transpose()` and `concatenate()`; `Quaternion` provides `normalize()`, `conjugate()`, `inverse()`, and `dot()` for rotation math. ```typescript import { Vector3, Quaternion, Matrix4 } from '@aspose/3d/utilities'; const position = new Vector3(1.0, 2.0, 3.0); const rotation = new Quaternion(1.0, 0.0, 0.0, 0.0); const transform = new Matrix4(); console.log(`length=${position.length} determinant=${transform.determinant}`); console.log(`rotation w=${rotation.w} x=${rotation.x} y=${rotation.y} z=${rotation.z}`); ``` ## See Also - [How to Load 3D Models in TypeScript](https://kb.aspose.org/3d/typescript/how-to-load-3d-models-in-typescript/) - [How to Export glTF in TypeScript](https://kb.aspose.org/3d/typescript/how-to-export-gltf-in-typescript/) - [Format Support](https://docs.aspose.org/3d/typescript/developer-guide/format-support/) - [API Reference](https://reference.aspose.org/3d/typescript/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) - [Aspose.3D for TypeScript — Enterprise Product](https://products.aspose.com/3d/typescript/) --- # Converting Between 3D Formats in TypeScript with Aspose.3D FOSS URL: https://blog.aspose.org/3d/typescript/convert-obj-gltf-fbx-typescript/ Learn how to convert 3D files between OBJ, glTF/GLB, STL, 3MF, FBX, and COLLADA formats in Node.js TypeScript applications using the @aspose/3d library. --- Product: Aspose.3D Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/3d/typescript/convert-obj-gltf-fbx-typescript/ --- # Converting Between 3D Formats in TypeScript with Aspose.3D FOSS Node.js developers working with 3D content frequently need to convert between formats: a design tool exports OBJ, a web renderer expects GLB, a 3D printer requires STL, and a manufacturing pipeline uses 3MF. Handling these conversions with a single, consistent API reduces the number of external tools in a pipeline and keeps conversion logic inside the application code where it can be tested and versioned. The `@aspose/3d` package (v24.12.0, MIT license) provides a TypeScript-first API for reading and writing all major 3D formats in Node.js. This guide walks through the most common conversion workflows. ## Installation Requirements: Node.js 18, 20, or 22; TypeScript 5.0 or later. The only runtime dependency is `xmldom`. ## Supported Formats The table below lists the formats covered in this guide and their read/write support. | Format | Extension | Read | Write | Notes | |---|---|:---:|:---:|---| | OBJ | `.obj` | Yes | Yes | Reads/writes `.mtl` material files | | glTF | `.gltf`, `.glb` | Yes | Yes | `.gltf` is JSON format; `.glb` is self-contained binary | | STL | `.stl` | Yes | Yes | Standard 3D printing format; binary and ASCII | | 3MF | `.3mf` | Yes | Yes | Manufacturing format with rich metadata | | FBX | `.fbx` | No* | No* | Importer/exporter exist but format auto-detection is not wired; not usable via `scene.open()` | | COLLADA | `.dae` | Yes | Yes | XML-based exchange format | OBJ supports both import and export. Load with `scene.open()` and save with `scene.save('output.obj')`, or convert to any other supported format such as glTF, STL, or 3MF. ## OBJ to GLB (Web Delivery) Converting OBJ to binary glTF (GLB) is the most common web workflow. GLB is a self-contained binary bundle: textures, geometry, and metadata in a single file, which makes it efficient for HTTP delivery and direct loading by Three.js, Babylon.js, and model-viewer. ```typescript import { Scene } from '@aspose/3d'; function convertObjToGlb(inputPath: string, outputPath: string): void { const scene = new Scene(); scene.open(inputPath); scene.save(outputPath); // extension '.glb' selects binary GLB format console.log(`Converted ${inputPath} -> ${outputPath}`); } convertObjToGlb('model.obj', 'model.glb'); ``` The output format is inferred from the file extension. Use `.glb` for binary GLB or `.gltf` for the separate JSON + `.bin` layout. ## OBJ to STL (3D Printing Prep) STL is the lingua franca of FDM and SLA 3D printing. Slicers such as PrusaSlicer, Bambu Studio, and Chitubox all accept STL. Converting from OBJ to STL is straightforward because both formats store triangle meshes. ```typescript import { Scene } from '@aspose/3d'; function convertObjToStl(inputPath: string, outputPath: string): void { const scene = new Scene(); scene.open(inputPath); scene.save(outputPath); // extension '.stl' selects STL format console.log(`STL written to ${outputPath}`); } convertObjToStl('part.obj', 'part.stl'); ``` STL does not store color, material, or UV data. If your OBJ file uses material groups, that information is dropped during export. For color-preserving print formats, consider 3MF instead (see below). ## STL to glTF (Scanner and CAD to Web) Structured-light scanners and parametric CAD exporters commonly output STL. Converting to glTF makes the geometry accessible in web-based viewers and AR platforms without a server-side rendering step. ```typescript import { Scene } from '@aspose/3d'; function convertStlToGltf(inputPath: string, outputPath: string): void { const scene = new Scene(); scene.open(inputPath); // extension '.gltf' saves as JSON + .bin sidecar scene.save(outputPath); console.log(`glTF written to ${outputPath}`); } convertStlToGltf('scan_output.stl', 'scan_output.gltf'); ``` Because STL carries no material or texture information, the resulting glTF file will contain geometry only. You can attach materials programmatically to scene nodes after loading if needed. ## 3MF to glTF (Manufacturing to Visualization) The 3D Manufacturing Format (3MF) is increasingly used in additive manufacturing workflows because it stores color, materials, component trees, and print metadata alongside geometry. Converting 3MF to glTF enables downstream visualization in web tools while preserving the scene structure. ```typescript import { Scene } from '@aspose/3d'; function convert3mfToGlb(inputPath: string, outputPath: string): void { const scene = new Scene(); scene.open(inputPath); scene.save(outputPath); // extension '.glb' selects binary GLB format console.log(`3MF -> GLB: ${outputPath}`); } convert3mfToGlb('assembly.3mf', 'assembly.glb'); ``` 3MF files often contain multi-component assemblies. The scene graph produced by `scene.open()` preserves the component hierarchy in `scene.rootNode.childNodes`, so you can inspect or manipulate individual parts before saving. ## Batch Conversion Pattern When processing a directory of files, wrap each conversion in a `try/catch` so that a single corrupt file does not abort the entire batch. ```typescript import { Scene } from '@aspose/3d'; import { readdirSync } from 'fs'; import { join, basename, extname } from 'path'; interface ConversionResult { input: string; output: string; success: boolean; error?: string; } function batchConvertToGlb( inputDir: string, outputDir: string, extensions: string[] = ['.obj', '.stl', '.3mf', '.dae'] // .fbx excluded: format auto-detection not wired ): ConversionResult[] { const results: ConversionResult[] = []; const files = readdirSync(inputDir).filter((f) => extensions.includes(extname(f).toLowerCase()) ); for (const file of files) { const inputPath = join(inputDir, file); const outputPath = join(outputDir, basename(file, extname(file)) + '.glb'); try { const scene = new Scene(); scene.open(inputPath); scene.save(outputPath); // extension '.glb' infers GLB format results.push({ input: inputPath, output: outputPath, success: true }); } catch (err) { const message = err instanceof Error ? err.message : String(err); results.push({ input: inputPath, output: outputPath, success: false, error: message }); console.error(`Failed to convert ${file}: ${message}`); } } const succeeded = results.filter((r) => r.success).length; console.log(`Batch complete: ${succeeded}/${results.length} files converted.`); return results; } // Usage batchConvertToGlb('./input', './output'); ``` The pattern above reads each supported file extension from an input directory, converts to GLB, and logs any failures without stopping the loop. The returned array of `ConversionResult` objects can be used for reporting or retry logic. ## Conclusion `@aspose/3d` covers the full range of format conversion needs in a Node.js TypeScript application with a consistent two-step API: `scene.open()` to load, `scene.save()` to write. The key constraint to remember is that FBX importer and exporter classes exist but format auto-detection is not yet wired, so FBX files cannot be loaded via `scene.open()`. For more detail on the `Scene`, `Node`, and `Mesh` classes used in these examples, see the class reference pages in this documentation. ## Getting Started - [Getting Started](https://docs.aspose.org/3d/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/3d/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/3d/typescript/) - [API Reference](https://reference.aspose.org/3d/typescript/) ## Related Resources - [Aspose.3D — Enterprise Blog](https://blog.aspose.com/) --- # Archive URL: https://blog.aspose.org/archive archives --- Product: archive Page Type: blog Canonical URL: https://blog.aspose.org/archive --- # Archive --- # Aspose.BarCode for Python URL: https://blog.aspose.org/barcode/python/ Tutorials and code examples for Aspose.BarCode FOSS for Python — barcode generation, encoding options, symbology configuration, and SVG/PNG rendering. --- Product: barcode Platform: python Page Type: index Canonical URL: https://blog.aspose.org/barcode/python/ --- # Aspose.BarCode for Python Browse tutorials and code examples for generating and encoding barcodes with Aspose.BarCode FOSS for Python. ## Related Resources - [Aspose.BarCode — Enterprise Blog](https://blog.aspose.com/) ## Related Topics - [Barcode Encode Options in Aspose.BarCode FOSS for Python](https://blog.aspose.org/barcode/python/barcode-encode-options-python/) - [Barcode Rendering to SVG and PNG in Python](https://blog.aspose.org/barcode/python/barcode-rendering-svg-png-python/) - [Introducing Aspose.BarCode FOSS for Python](https://blog.aspose.org/barcode/python/introducing-barcode-foss-python/) --- # Barcode Encode Options in Aspose.BarCode FOSS for Python URL: https://blog.aspose.org/barcode/python/barcode-encode-options-python/ Configure Code 128, Code 39, QR Code, EAN, and UPC barcode generation with symbology-specific encode options and rendering controls in Aspose.BarCode FOSS for Python. MIT licensed, pure Python. --- Product: barcode Platform: python Page Type: index Canonical URL: https://blog.aspose.org/barcode/python/barcode-encode-options-python/ --- # Barcode Encode Options in Aspose.BarCode FOSS for Python ## Introduction Aspose.BarCode FOSS for Python provides per-symbology option classes that control encoding behavior across all seven supported barcode formats. Each option class inherits from `EncodeOptions` and adds properties specific to its symbology — Code 128 encode modes, Code 39 ASCII selection, QR error correction levels, and EAN/UPC check digit handling. This post covers each option class, its properties, and working code examples. Classes are available from the top-level `aspose_barcode_foss` package. --- ## Key Features ### Code 128 Encode Modes `Code128Options` controls which Code 128 character sets the encoder uses. The `encode_mode` property accepts a `Code128EncodeMode` enum value: `AUTO`, `CODE_A`, `CODE_B`, `CODE_C`, `CODE_AB`, `CODE_AC`, or `CODE_BC`. AUTO selects the most compact encoding automatically. CODE_C is optimized for digit-only data (pairs of digits encoded as single code points). ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import Code128Options, Code128EncodeMode bc = barcode.code128( "1234567890", encode=Code128Options(encode_mode=Code128EncodeMode.CODE_C), ) svg = bc.to_svg() ``` Code 128 also supports `gs1_enabled` and `eci_assignment_number` properties inherited from `EncodeOptions` for GS1 and ECI metadata. ### Code 39 Encoding `Code39Options` controls whether the encoder uses the base 43-character set or the Full ASCII extension. Set `full_ascii=True` to enable Full ASCII mode, which encodes the full 128-character ASCII range using shift pairs. The optional `add_check_digit` property appends a modulo-43 check digit. ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import Code39Options bc = barcode.code39( "Hello", encode=Code39Options(full_ascii=True, add_check_digit=True), ) svg = bc.to_svg() ``` ### QR Code Configuration `QrOptions` offers the richest configuration set among the supported symbologies: - `error_correction_level`: `QrErrorCorrectionLevel.L` (7%), `.M` (15%), `.Q` (25%), `.H` (30%) - `encoding_mode`: `QrEncodeMode.AUTO`, `.NUMERIC`, `.ALPHANUMERIC`, `.BYTE`, `.KANJI` - `version`: QR version (1–40), controlling symbol size - `mask`: mask pattern (0–7) for manual selection ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import QrOptions, QrErrorCorrectionLevel, QrEncodeMode bc = barcode.qr( "https://example.com/product/12345", encode=QrOptions( error_correction_level=QrErrorCorrectionLevel.Q, encoding_mode=QrEncodeMode.BYTE, ), ) png_bytes = bc.to_png() ``` ### EAN and UPC Check Digits `Ean13Options`, `Ean8Options`, `UpcaOptions`, and `UpceOptions` each have an `allow_check_digit_input` property. By default, the library computes the check digit automatically from the data. Set `allow_check_digit_input=True` if your data already includes the check digit. ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import Ean13Options # Automatic check digit (12 digits in, library appends the 13th) bc = barcode.ean13("590123412345") svg = bc.to_svg() # Pre-computed check digit (13 digits, library validates) bc2 = barcode.ean13( "5901234123457", encode=Ean13Options(allow_check_digit_input=True), ) ``` ### Rendering Options `RenderOptions` applies to all symbologies and controls the visual output. Pass it to `to_svg()` or `to_png()`: | Property | Type | Description | |---|---|---| | `scale` | `float` | Uniform scale multiplier | | `dpi` | `int` | Resolution for PNG output | | `module_width` | `float` | Width of one barcode module | | `module_height` | `float` | Height of one barcode module | | `quiet_zone` | `float` | Whitespace padding around the barcode | | `foreground_color` | `str` | Hex color for bars (e.g., `"#000000"`) | | `background_color` | `str` | Hex color for background | | `transparent_background` | `bool` | Transparent background for PNG | | `show_text` | `bool` | Show human-readable text below barcode | | `font_family` | `str` | Font for human-readable text | | `font_size` | `float` | Font size for human-readable text | ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import RenderOptions bc = barcode.upca("01234567890") png = bc.to_png(options=RenderOptions( scale=3.0, dpi=300, foreground_color="#1a1a1a", background_color="#ffffff", show_text=True, font_family="Courier New", )) ``` ### Error Handling All encode option validation happens at parse time. If invalid data or incompatible options are provided, the library raises a typed exception before any encoding begins: - `InvalidInputError` — data contains characters not supported by the symbology - `EncodingError` — encoding fails (e.g., data exceeds capacity) - `SymbologyNotFoundError` — unrecognized symbology name passed to `generate()` - `UnsupportedCapabilityError` — requested feature not available for this symbology All exception classes inherit from `BarcodeError`. --- ## Quick Start Generate barcodes with different encode options and save them: ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import ( Code128Options, Code128EncodeMode, QrOptions, QrErrorCorrectionLevel, RenderOptions, ) # Code 128 in CODE_C mode (compact digit encoding) c128 = barcode.code128( "9876543210", encode=Code128Options(encode_mode=Code128EncodeMode.CODE_C), ) with open("code128.svg", "w") as f: f.write(c128.to_svg()) # QR with high error correction qr = barcode.qr( "https://example.com", encode=QrOptions(error_correction_level=QrErrorCorrectionLevel.H), ) with open("qr.png", "wb") as f: f.write(qr.to_png(options=RenderOptions(scale=4.0))) # EAN-13 with custom colors ean = barcode.ean13("590123412345") with open("ean13.svg", "w") as f: f.write(ean.to_svg(options=RenderOptions( foreground_color="#003366", show_text=True, ))) ``` --- ## Supported Formats | Symbology | Type | Options Class | Key Properties | |---|---|---|---| | Code 128 | 1D | `Code128Options` | `encode_mode` | | Code 39 | 1D | `Code39Options` | `full_ascii`, `add_check_digit` | | EAN-13 | 1D | `Ean13Options` | `allow_check_digit_input` | | EAN-8 | 1D | `Ean8Options` | `allow_check_digit_input` | | QR Code | 2D | `QrOptions` | `error_correction_level`, `encoding_mode`, `version`, `mask` | | UPC-A | 1D | `UpcaOptions` | `allow_check_digit_input` | | UPC-E | 1D | `UpceOptions` | `allow_check_digit_input` | Output formats: | Format | Extension | Export | |---|---|:---:| | SVG | `.svg` | ✓ | | PNG | `.png` | ✓ | --- ## Open Source & Licensing Aspose.BarCode FOSS for Python is MIT licensed. The source is available on [GitHub](https://github.com/aspose-barcode-foss/Aspose.BarCode-FOSS-for-Python); build from source. No native dependencies, no telemetry, no usage limits. --- ## Getting Started - [Getting Started](https://docs.aspose.org/barcode/python/getting-started/) - [Developer Guide](https://docs.aspose.org/barcode/python/developer-guide/) - [KB Articles](https://kb.aspose.org/barcode/python/) - [API Reference](https://reference.aspose.org/barcode/python/) - [Source Repository: aspose-barcode-foss](https://github.com/aspose-barcode-foss/Aspose.BarCode-FOSS-for-Python) ## Related Resources - [Aspose.BarCode for Python Enterprise Product](https://products.aspose.com/barcode/python-net/) - [Aspose.BarCode — Enterprise Blog](https://blog.aspose.com/) --- # Barcode Rendering to SVG and PNG in Python URL: https://blog.aspose.org/barcode/python/barcode-rendering-svg-png-python/ How to render barcodes to SVG and PNG using Aspose.BarCode FOSS for Python. Covers RenderOptions for scale, DPI, colors, quiet zone, and human-readable text, plus SvgRenderer and PngRenderer usage. --- Product: barcode Platform: python Page Type: index Canonical URL: https://blog.aspose.org/barcode/python/barcode-rendering-svg-png-python/ --- # Barcode Rendering to SVG and PNG in Python ## Introduction Aspose.BarCode FOSS for Python generates barcodes in seven symbologies and renders them to SVG and PNG. This post focuses on the rendering pipeline — how to control output format, dimensions, colors, and human-readable text using `RenderOptions`, `SvgRenderer`, and `PngRenderer`. The library is distributed as `aspose-barcode-foss`, released under the MIT license with no native dependencies. Every barcode object exposes `to_svg()` and `to_png()` convenience methods, plus a lower-level `render()` method that accepts any `Renderer` implementation. --- ## Key Features ### SVG Output with SvgRenderer `SvgRenderer` produces resolution-independent SVG markup. The `Barcode.to_svg()` method is a shortcut that uses `SvgRenderer` internally. ```python from aspose_barcode_foss import BarcodeService, RenderOptions from aspose_barcode_foss.rendering import SvgRenderer service = BarcodeService() barcode = service.generate("code128", "RENDER-TEST-001") # Direct convenience method svg_string = barcode.to_svg(RenderOptions(scale=2.0)) # Explicit renderer usage renderer = SvgRenderer() result = barcode.render(renderer, RenderOptions(scale=2.0, show_text=True)) ``` ### PNG Output with PngRenderer `PngRenderer` produces raster PNG images. Control resolution with the `dpi` property on `RenderOptions`. The `Barcode.to_png()` method is the convenience shortcut. ```python from aspose_barcode_foss import BarcodeService, RenderOptions from aspose_barcode_foss.rendering import PngRenderer service = BarcodeService() barcode = service.generate("ean13", "590123412345") # Convenience method — returns bytes png_bytes = barcode.to_png(RenderOptions(dpi=300, scale=3.0)) with open("barcode.png", "wb") as f: f.write(png_bytes) ``` ### Controlling Scale and DPI `RenderOptions` provides `scale` (multiplier for module dimensions) and `dpi` (dots per inch for raster output). These work together: `scale` affects the logical size of bars and spaces, while `dpi` controls pixel density in PNG output. ```python from aspose_barcode_foss import RenderOptions # High-resolution print label print_options = RenderOptions(scale=4.0, dpi=600) # Screen display screen_options = RenderOptions(scale=1.0, dpi=96) ``` ### Colors and Background Set `foreground_color` and `background_color` as CSS color strings. Enable `transparent_background` to omit the background fill (useful for overlaying on existing designs). ```python from aspose_barcode_foss import BarcodeService, RenderOptions service = BarcodeService() barcode = service.generate("qrcode", "https://example.com") options = RenderOptions( foreground_color="#003366", background_color="#FFFFFF", scale=3.0, ) svg = barcode.to_svg(options) ``` ### Quiet Zone Control The `quiet_zone` property sets the blank margin around the barcode in module-width units. Most barcode standards require a minimum quiet zone for reliable scanning. ```python from aspose_barcode_foss import BarcodeService, RenderOptions service = BarcodeService() barcode = service.generate("code39", "QUIET-ZONE") # Wider quiet zone for print use options = RenderOptions(quiet_zone=10.0, scale=2.0) svg = barcode.to_svg(options) ``` ### Human-Readable Text Set `show_text=True` to display the encoded data below the barcode. The `font_family` and `font_size` properties control the text appearance. ```python from aspose_barcode_foss import BarcodeService, RenderOptions service = BarcodeService() barcode = service.generate("upca", "01234567890") options = RenderOptions( show_text=True, font_family="monospace", font_size=12.0, scale=2.5, ) svg = barcode.to_svg(options) ``` --- ## Quick Start ```python from aspose_barcode_foss import BarcodeService, RenderOptions service = BarcodeService() # Generate a Code 128 barcode barcode = service.generate("code128", "HELLO-2026") # Render to SVG with custom options options = RenderOptions( scale=2.0, show_text=True, foreground_color="#000000", background_color="#FFFFFF", quiet_zone=4.0, ) svg_output = barcode.to_svg(options) with open("hello.svg", "w") as f: f.write(svg_output) # Render to PNG at 300 DPI png_bytes = barcode.to_png(RenderOptions(dpi=300, scale=3.0)) with open("hello.png", "wb") as f: f.write(png_bytes) ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | SVG | .svg | — | ✓ | | PNG | .png | — | ✓ | Note: `PdfRenderer` exists in the API but raises `NotImplementedError` in the current release. --- ## Open Source & Licensing Aspose.BarCode FOSS for Python is released under the MIT License. The source code is hosted on GitHub. You can use, modify, and redistribute the library in both open-source and commercial projects. --- ## Getting Started - [Getting Started](https://docs.aspose.org/barcode/python/getting-started/) - [Developer Guide](https://docs.aspose.org/barcode/python/developer-guide/) - [KB Articles](https://kb.aspose.org/barcode/python/) - [API Reference](https://reference.aspose.org/barcode/python/) - [Troubleshooting](https://kb.aspose.org/barcode/python/troubleshooting/) ## Related Resources - [Aspose.BarCode for Python — Enterprise Product](https://products.aspose.com/barcode/python-net/) - [Aspose.BarCode — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.BarCode FOSS for Python URL: https://blog.aspose.org/barcode/python/introducing-barcode-foss-python/ Aspose.BarCode FOSS for Python is a free, MIT-licensed library for generating Code 128, Code 39, EAN-13, EAN-8, QR Code, UPC-A, and UPC-E barcodes in pure Python. Renders to SVG and PNG with no native dependencies. --- Product: barcode Platform: python Page Type: index Canonical URL: https://blog.aspose.org/barcode/python/introducing-barcode-foss-python/ --- # Introducing Aspose.BarCode FOSS for Python ## Introduction We are releasing **Aspose.BarCode FOSS for Python**, a pure-Python library for generating standards-compliant 1D and 2D barcodes. The source is available on [GitHub](https://github.com/aspose-barcode-foss/Aspose.BarCode-FOSS-for-Python) as `aspose-barcode-foss`, carries an MIT license, and has zero external dependencies. The library supports seven symbologies: Code 128, Code 39, EAN-13, EAN-8, QR Code, UPC-A, and UPC-E. Each barcode renders directly to SVG or PNG. There are no native extensions, no system packages to install, and no graphics drivers required — build from source on Windows, Linux, and macOS. --- ## Key Features ### High-Level Generation API The top-level `generate()` function accepts a symbology name and data string, returning a `Barcode` object. Dedicated per-symbology helpers — `code128()`, `code39()`, `ean13()`, `ean8()`, `qr()`, `upca()`, and `upce()` — provide type-safe entry points for each format. ```python import aspose_barcode_foss as barcode bc = barcode.generate("code128", "ABC123") svg = bc.to_svg() ``` ### Symbology-Specific Encode Options Each symbology accepts an options class that controls encoding behavior. `Code128Options` provides `encode_mode` (AUTO, CODE_A, CODE_B, CODE_C, CODE_AB, CODE_AC, CODE_BC). `Code39Options` supports BASE and FULL_ASCII modes. `QrOptions` exposes `error_correction_level` (L, M, Q, H), `version`, `mask`, and `encoding_mode` (AUTO, NUMERIC, ALPHANUMERIC, BYTE, KANJI). ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import QrOptions, QrErrorCorrectionLevel bc = barcode.qr( "https://example.com", encode=QrOptions(error_correction_level=QrErrorCorrectionLevel.H), ) png_bytes = bc.to_png() ``` ### Rendering Controls `RenderOptions` controls the visual output: `scale`, `dpi`, `module_width`, `module_height`, `quiet_zone`, `foreground_color`, `background_color`, `transparent_background`, `show_text`, `font_family`, and `font_size`. Both `to_svg()` and `to_png()` accept an optional `RenderOptions` parameter. ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import RenderOptions bc = barcode.ean13("590123412345") svg = bc.to_svg(options=RenderOptions( scale=2.0, foreground_color="#003366", quiet_zone=10.0, show_text=True, )) ``` ### Automatic Check Digits EAN-13, EAN-8, UPC-A, and UPC-E compute check digits automatically from the data string. You supply only the payload digits; the library appends the correct check digit during encoding. ### Input Validation Each symbology has a dedicated `InputParser` that validates data before encoding. Invalid characters, incorrect lengths, and format violations are caught early with typed exceptions: `InvalidInputError`, `EncodingError`, `SymbologyNotFoundError`, and `UnsupportedCapabilityError` — all inheriting from `BarcodeError`. --- ## Quick Start Generate a Code 128 barcode and write the SVG to a file: ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import RenderOptions bc = barcode.code128("Hello World") svg = bc.to_svg(options=RenderOptions(show_text=True)) with open("barcode.svg", "w") as f: f.write(svg) ``` Generate a QR code and save it as PNG: ```python import aspose_barcode_foss as barcode from aspose_barcode_foss import QrOptions, QrErrorCorrectionLevel bc = barcode.qr( "https://example.com", encode=QrOptions(error_correction_level=QrErrorCorrectionLevel.H), ) with open("qr.png", "wb") as f: f.write(bc.to_png()) ``` The library requires Python 3.12 or later. --- ## Supported Formats | Symbology | Type | Check Digit | Options Class | |---|---|:---:|---| | Code 128 | 1D | Built-in | `Code128Options` | | Code 39 | 1D | Optional | `Code39Options` | | EAN-13 | 1D | Automatic | `Ean13Options` | | EAN-8 | 1D | Automatic | `Ean8Options` | | QR Code | 2D | Built-in | `QrOptions` | | UPC-A | 1D | Automatic | `UpcaOptions` | | UPC-E | 1D | Automatic | `UpceOptions` | Output formats: | Format | Extension | Export | |---|---|:---:| | SVG | `.svg` | ✓ | | PNG | `.png` | ✓ | --- ## Open Source & Licensing The library is MIT licensed. You can use it in commercial applications, modify it, and redistribute it without restriction. The source is available on [GitHub](https://github.com/aspose-barcode-foss/Aspose.BarCode-FOSS-for-Python). There are no usage tiers, no token limits, and no telemetry. All processing happens locally. --- ## Getting Started - [Getting Started](https://docs.aspose.org/barcode/python/getting-started/) - [Developer Guide](https://docs.aspose.org/barcode/python/developer-guide/) - [KB Articles](https://kb.aspose.org/barcode/python/) - [API Reference](https://reference.aspose.org/barcode/python/) - [Source Repository: aspose-barcode-foss](https://github.com/aspose-barcode-foss/Aspose.BarCode-FOSS-for-Python) ## Related Resources - [Aspose.BarCode for Python Enterprise Product](https://products.aspose.com/barcode/python-net/) - [Aspose.BarCode — Enterprise Blog](https://blog.aspose.com/) --- # Inside the Aspose.Cells FOSS Data Model in C++ URL: https://blog.aspose.org/cells/cpp/cells-foss-model-in-cpp/ A look at the Core data-model layer beneath Aspose.Cells FOSS for C++'s Workbook and Worksheet API — the plain-value records for cells, styles, document properties, and load diagnostics — and when a consumer would read or write them directly instead of going through the facade classes. --- Product: Aspose.Cells Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/cells/cpp/cells-foss-model-in-cpp/ --- # Inside the Aspose.Cells FOSS Data Model in C++ ## Introduction Aspose.Cells FOSS for C++ is built as two layers. The layer most code touches is the facade: `Workbook`, `Worksheet`, `Cell`, and `Style`, which is what the announcement and feature posts for this platform cover. Underneath it sits a second layer, in the `Aspose::Cells_FOSS::Core` namespace, made up of plain data records — `WorkbookModel`, `WorksheetModel`, `CellRecord`, `StyleValue`, and roughly four dozen related `*Model` and `*Value` types. These records hold the actual parsed spreadsheet state: cell values keyed by `CellAddress`, style attributes as `StyleValue`, workbook and worksheet settings, page setup, filters, and load diagnostics. The facade classes read from and write to this layer rather than storing state themselves. The bridge between the two layers is explicit and public. `Workbook::GetModel()` returns a `Core::WorkbookModel`, `Worksheet::GetModel()` returns a `Core::WorksheetModel`, and `Style::ToCore()` / `Style::FromCore()` convert a mutable `Style` to and from a `Core::StyleValue`. `DocumentProperties::GetModel()` and `ExtendedDocumentProperties::GetModel()` do the same for document metadata. A consumer reaches for this layer directly in a narrower set of cases than the everyday cell-editing API: inspecting the `DiagnosticBag` recorded while a workbook was loaded or saved, normalizing a style through the workbook-level `StyleRepository`, or working with the plain-old-data cell and row records directly instead of the `Cell` / `Row` wrapper objects. Everything described here ships in the same MIT-licensed, dependency-free source tree as the rest of Aspose.Cells FOSS for C++, built with CMake and included as headers and source rather than a prebuilt binary. If you have not worked with the facade API yet, start with the Workbook/Worksheet/Cell features post first — this post assumes that grounding and focuses on what sits underneath it. --- ## What's Included ### The Workbook and Worksheet Model Tree `Core::WorkbookModel` is the root record. `GetWorksheets()` returns a `std::deque`, `GetSettings()` a `WorkbookSettingsModel`, `GetProperties()` a `WorkbookPropertiesModel`, `GetDocumentProperties()` a `DocumentPropertiesModel`, `GetDiagnostics()` a `DiagnosticBag`, `GetStyles()` a `StyleRepository`, `GetSharedStrings()` a `SharedStringRepository`, and `GetDefaultStyle()` / `SetDefaultStyle()` a `StyleValue`. It also tracks `GetActiveSheetIndex()` and a `std::vector` from `GetDefinedNames()`. `Workbook::GetModel()` is the entry point to this record. `Core::WorksheetModel`, reached through `Worksheet::GetModel()`, stores cells as `std::unordered_map` via `GetCells()`, rows as `std::unordered_map` via `GetRows()`, column ranges as `std::vector` via `GetColumns()`, and merged ranges as `std::vector` via `GetMergeRegions()`. It also carries `GetHyperlinks()`, `GetValidations()`, `GetConditionalFormattings()`, `GetPageSetup()`, `GetView()`, `GetProtection()`, `GetAutoFilter()`, `GetTabColor()`, and `GetVisibility()` (a `SheetVisibility` value: `Visible`, `Hidden`, or `VeryHidden`). `CellAddress` is the hashable key type used for that cell map. It parses A1-style text into zero-based row/column indexes and back — this is one of the few classes in this cluster with direct test coverage in the FOSS repo: ```cpp #include "aspose/cells_foss/core/CellAddress.h" using namespace Aspose::Cells_FOSS; Core::CellAddress parsed = Core::CellAddress::Parse("AB3"); // parsed.GetRowIndex() == 2 (zero-based row index) // parsed.GetColumnIndex() == 27 (zero-based column index) // parsed.ToString() == "AB3" ``` `CellRecord` holds a cell's `CellValue`, `CellValueKind`, an optional formula string, a `StyleValue`, and a `GetIsExplicitlyStored()` flag that distinguishes a cell that was actually written from one that only exists because a row or column default touches it. `RowModel` carries an optional height, a hidden flag, and an optional style index; `ColumnRangeModel` carries the same three plus the min/max column span it applies to. `MergeRegion` is a plain first-row/first-column/total-rows/total-columns rectangle. ### Style Data as Plain Values `StyleValue` is the `Core` counterpart to the mutable `Style` facade — `Style::ToCore()` converts a `Style` to one, and `Style::FromCore()` builds a `Style` from one. It groups `GetFont()` (`FontValue`), `GetPattern()` (`FillPatternKind`), `GetForegroundColor()` / `GetBackgroundColor()` (`ColorValue`), `GetBorders()` (`BordersValue`), `GetAlignment()` (`AlignmentValue`), `GetProtection()` (`ProtectionValue`), and `GetNumberFormat()` (`NumberFormatValue`), plus a static `StyleValue::Default()` and a `Clone()`. `FontValue` mirrors `Font` field for field: name, size, bold, italic, underline, strike-through, and a `ColorValue`. `ColorValue` itself is a plain ARGB tuple (`GetA()`, `GetR()`, `GetG()`, `GetB()`, `Equals()`, `GetHashCode()`) — unlike the facade `Color` class it has no `FromArgb()`-style factory, so a `ColorValue` is normally obtained from an existing style rather than constructed directly. `BordersValue` holds five `BorderSideValue` members — left, right, top, bottom, and diagonal — each pairing a `BorderStyle` enum value with a `ColorValue`. `AlignmentValue` models horizontal and vertical alignment, wrap text, indent level, text rotation, shrink-to-fit, and reading order. `ProtectionValue` and `NumberFormatValue` back the cell-protection flags and the number-format id/custom-string pair that `Style` exposes. `StyleRepository`, reached through `WorkbookModel::GetStyles()`, exposes one operation: `Normalize(style) -> StyleValue`. The workbook uses it internally while loading and saving to intern equivalent styles rather than duplicating identical `StyleValue` records — it is not a general-purpose style cache with index-based lookup in the current API surface. ### Document Properties and Workbook-Level Settings `DocumentPropertiesModel` groups `GetCore()` (`CoreDocumentPropertiesModel`: title, subject, creator, keywords, description, last-modified-by, revision, category, content status, and `created`/`modified` timestamps) and `GetExtended()` (`ExtendedDocumentPropertiesModel`: application, app version, company, manager, doc security, hyperlink base, and the scale-crop / links-up-to-date / shared-doc flags). `DocumentProperties::GetModel()` and `ExtendedDocumentProperties::GetModel()` bridge from the facade classes to these records. `WorkbookPropertiesModel` mirrors `WorkbookProperties` — code name, show-objects, filter privacy, backup-file, and related flags — and nests `WorkbookProtectionModel` (lock structure/windows/revision, workbook and revisions password), `WorkbookViewModel` (window position and size, first visible sheet, scroll-bar and sheet-tab visibility, tab ratio, minimized state, auto-filter date grouping), and `CalculationPropertiesModel` (calculation mode, iteration settings, full precision, concurrent calculation). `WorkbookSettingsModel` carries a `DateSystem` value (`Windows1900` or `Mac1904`) and a display culture — the model-level counterpart of `WorkbookSettings::GetDate1904()` / `GetCulture()`. Most `*Model` types in this group expose `CopyFrom(source)` and `HasStoredState()`, which the serializer uses to tell an explicitly-set value from an unset default before writing XML. ### Worksheet Feature Models `WorksheetProtectionModel` mirrors `WorksheetProtection` field for field and adds the stored password fields — `GetPasswordHash()`, `GetAlgorithmName()`, `GetHashValue()`, `GetSaltValue()`, `GetSpinCount()` — that the facade `WorksheetProtection` does not surface directly. `WorksheetViewModel` holds grid-line, header, and zero visibility, right-to-left layout, and zoom scale. `PageSetupModel` nests `PageMarginsModel` (left/right/top/bottom/header/footer margins as doubles), `PrintOptionsModel` (grid lines, headings, horizontal and vertical centering), and `HeaderFooterModel` (left/center/right header and footer text), alongside paper size, orientation, scale, fit-to-width/height, print area, print title rows/columns, and page-break vectors. `AutoFilterModel` holds a range string, a `std::vector`, and an `AutoFilterSortStateModel`. `FilterColumnModel` in turn nests `AutoFilterColorFilterModel`, `AutoFilterDynamicFilterModel`, and `AutoFilterTop10Model`, plus a plain list of filter value strings and a `std::vector`. `ConditionalFormattingModel` pairs a `std::vector` with a `std::vector` — each condition carrying its type, operator, formulas, color-scale/data-bar/icon-set fields, and a `StyleValue` for the resulting format. `ValidationModel` and `HyperlinkModel` mirror the `Validation` and `Hyperlink` facades as plain records, and `DefinedNameModel` mirrors `DefinedName`. `SheetVisibility` is the model-layer enum behind `Worksheet::GetVisibilityType()`. Some of the facade features that these records back — `AutoFilter` and `ConditionalFormattingCollection` in particular — are called out in the product documentation as still under active development in this release. Treat the shapes above as the structural target the model and serializer are built around rather than a guarantee that every field round-trips through a saved workbook today. ### Diagnostics and Shared State `DiagnosticBag`, reached via `WorkbookModel::GetDiagnostics()`, collects `DiagnosticEntry` records — each with a `GetCode()`, a `GetSeverity()` (`DiagnosticSeverity`: `Warning`, `Recoverable`, or `LossyRecoverable`), a `GetMessage()`, a `GetRepairApplied()` flag, and a `GetDataLossRisk()` flag — generated while a workbook is parsed or serialized. This runs alongside `Workbook::GetLoadDiagnostics()`, whose facade-level `LoadDiagnostics` / `LoadIssue` types share the same `DiagnosticSeverity` enum; code that needs the raw model record instead of the `LoadIssue` wrapper reaches it through `GetDiagnostics()` on the workbook model. `SharedStringRepository` backs the xlsx shared-strings table: `GetValues()` returns the interned string vector, `TryGetValue(index, value)` resolves an index back to text, and `Intern(value)` adds or reuses an entry — used internally when `SaveOptions::SetUseSharedStrings(true)` is set. `DateSerialConverter` converts between a `DateTime` and the OLE-style serial number Excel stores in a cell, taking a `DateSystem` so 1900- and 1904-based workbooks decode to the same calendar date. --- ## Quick Start Add the library to a CMake project as a subdirectory and link the target it defines: ```cmake add_subdirectory(path/to/Aspose.Cells-FOSS-for-Cpp) target_link_libraries(MyApp PRIVATE Aspose.Cells.Foss.Cpp) ``` The example below writes a cell through the facade, then reaches into the underlying model for a diagnostic bag and a `CellAddress` parse — the same operation `WorksheetModel::GetCells()` uses internally to key its cell map: ```cpp #include "aspose/cells_foss/Workbook.h" #include "aspose/cells_foss/Worksheet.h" #include "aspose/cells_foss/Cell.h" #include "aspose/cells_foss/core/CellAddress.h" #include using namespace Aspose::Cells_FOSS; int main() { Workbook workbook; Worksheet& sheet = workbook.GetWorksheets()[0]; sheet.SetName("Report"); sheet.GetCells()["A1"].PutValue("Total"); workbook.Save("report.xlsx"); Core::CellAddress address = Core::CellAddress::Parse("A1"); std::cout << "Row: " << address.GetRowIndex() << " Column: " << address.GetColumnIndex() << "\n"; for (const auto& entry : workbook.GetModel().GetDiagnostics().GetEntries()) { std::cout << "Diagnostic: " << entry.GetMessage() << "\n"; } return 0; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | XLSX | `.xlsx` | ✓ | ✓ | The model layer described here is the in-memory representation the xlsx reader and writer operate on; it is not itself tied to any additional file format beyond the Xlsx import/export the rest of the library supports. --- ## Open Source & Licensing Aspose.Cells FOSS for C++ is MIT licensed. Source code, including the `Aspose::Cells_FOSS::Core` model headers referenced in this post, is on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Cpp); commercial use, modification, and redistribution are permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/cpp/developer-guide/) - [Working with the Cells FOSS Model](https://docs.aspose.org/cells/cpp/developer-guide/working-with-cells-foss-model/) - [KB Articles](https://kb.aspose.org/cells/cpp/) - [API Reference](https://reference.aspose.org/cells/cpp/) - [Product Page](https://products.aspose.org/cells/cpp/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Spreadsheet Management in C++ with Aspose.Cells FOSS URL: https://blog.aspose.org/cells/cpp/cells-spreadsheet-management-cpp/ Aspose.Cells FOSS for C++ models spreadsheet management around Workbook, Worksheet, and Cells: typed cell values and formulas, Style-based formatting with Font, Color, and Borders, PageSetup for print layout, and Hyperlink, DefinedName, and Validation objects for structure — all reading and writing native XLSX files with no Microsoft Excel dependency. --- Product: Aspose.Cells Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/cells/cpp/cells-spreadsheet-management-cpp/ --- # Spreadsheet Management in C++ with Aspose.Cells FOSS ## Introduction Spreadsheet management is the part of Aspose.Cells FOSS for C++ that most programs touch first: the `Workbook` that owns the file, the `Worksheet` objects inside it, and the `Cells` collection that holds values, formulas, and formatting. This post walks through that surface in more depth than a general introduction — how workbooks and worksheets are created and navigated, how cell values and formulas are read and written, how `Style`, `Font`, `Color`, and `Borders` combine to format output, and how `PageSetup`, `Hyperlink`, `DefinedName`, and `Validation` add structure around the raw grid of cells. Every class covered here is part of the native C++ API declared under `aspose/cells_foss/` headers. There is no COM interop and no dependency on Microsoft Excel being installed — the library reads and writes the `.xlsx` package format directly, which is also why the current release supports `.xlsx` only, on both the load and save sides. The examples below build on each other: a workbook is created, worksheets and cells are populated, styling is applied, and the file is saved and reloaded to confirm the round trip. All code is adapted from the library's own compatibility, golden, and unit test suites, so it reflects operations that are exercised against real `.xlsx` output. --- ## Key Features ### Workbook and Worksheet Management A `Workbook` starts with one worksheet in its `WorksheetCollection`. Worksheets are added with `Add()`, looked up by index or by name, and renamed with `SetName()`. `WorksheetCollection` also tracks which sheet is active: ```cpp #include "aspose/cells_foss/Workbook.h" #include "aspose/cells_foss/Worksheet.h" using namespace Aspose::Cells_FOSS; Workbook workbook; Worksheet& sheet = workbook.GetWorksheets()[0]; sheet.SetName("Data"); int summaryIndex = workbook.GetWorksheets().Add("Summary"); workbook.GetWorksheets().SetActiveSheetIndex(0); int sheetCount = workbook.GetWorksheets().GetCount(); // 2 ``` Saving and reloading go through the same `Workbook` type. `Workbook::Save()` accepts a file path, and a `Workbook` can be constructed directly from a path or from an in-memory byte buffer, which round-trips cell values and formulas: ```cpp workbook.Save("report.xlsx"); Workbook loaded("report.xlsx"); Worksheet& reloadedSheet = loaded.GetWorksheets()["Data"]; ``` ### Cell Values and Formulas `Cells`, reached through `Worksheet::GetCells()`, indexes cells by A1-style reference. `Cell::PutValue()` accepts strings, integers, doubles, and booleans, `SetFormula()` stores an Excel formula string, and `GetValue()` returns a `CellValue` with typed accessors (`AsString()`, `AsInteger()`, `AsDouble()`, `AsBool()`, `AsDateTime()`): ```cpp Cells& cells = sheet.GetCells(); cells["A1"].PutValue("Category"); cells["B1"].PutValue("Amount"); cells["A2"].PutValue("Travel"); cells["B2"].PutValue(482.50); cells["A3"].PutValue("Supplies"); cells["B3"].PutValue(129.99); cells["B4"].SetFormula("=SUM(B2:B3)"); CellValue amount = cells["B2"].GetValue(); if (amount.IsDouble()) { double value = amount.AsDouble(); } std::string formula = cells["B4"].GetFormula(); ``` `Cell::GetType()` reports the stored `CellValueType` (`Blank`, `String`, `Number`, `Boolean`, `DateTime`, or `Formula`), and `GetDisplayStringValue()` returns the value formatted the way it would appear in Excel, honoring whatever number format is applied through `Style`. ### Styling with Style, Font, Color, and Borders `Cell::GetStyle()` returns a `Style` object that can be modified and reapplied with `SetStyle()`. `Style` exposes a `Font`, a `Borders` set, fill pattern and color, alignment, and number format: ```cpp #include "aspose/cells_foss/Style.h" #include "aspose/cells_foss/Color.h" Cell headerCell = sheet.GetCells()["A1"]; Style style = headerCell.GetStyle(); Font font = style.GetFont(); font.SetBold(true); font.SetColor(Color::FromArgb(255, 255, 255, 255)); style.SetFont(font); style.SetPattern(FillPattern::Solid); style.SetForegroundColor(Color::FromArgb(255, 34, 120, 212)); style.SetHorizontalAlignment(HorizontalAlignmentType::Center); Borders borders = style.GetBorders(); Border bottomBorder = borders.GetBottom(); bottomBorder.SetLineStyle(BorderStyleType::Thin); borders.SetBottom(bottomBorder); style.SetBorders(borders); style.SetNumberFormat("#,##0.00"); headerCell.SetStyle(style); ``` `Style` is a value type: reading it back with `GetStyle()` reflects whatever was last set with `SetStyle()`, which makes it straightforward to build one style and apply it across a header row or a range of data cells. ### Page Setup and Print Configuration `Worksheet::GetPageSetup()` returns a `PageSetup` object covering paper size, orientation, margins, scaling, print titles, and page breaks: ```cpp #include "aspose/cells_foss/PageSetup.h" PageSetup& pageSetup = sheet.GetPageSetup(); pageSetup.SetOrientation(PageOrientationType::Landscape); pageSetup.SetPaperSize(PaperSizeType::PaperA4); pageSetup.SetFitToPagesWide(1); pageSetup.SetFitToPagesTall(0); pageSetup.SetPrintArea("$A$1:$D$20"); pageSetup.SetPrintTitleRows("$1:$1"); pageSetup.SetLeftMargin(0.5); pageSetup.SetCenterFooter("Page &P of &N"); pageSetup.AddHorizontalPageBreak(20); ``` Margins are available in both raw units (`GetLeftMargin()`) and inches (`GetLeftMarginInch()`), and `GetHorizontalPageBreaks()` / `GetVerticalPageBreaks()` return the page break positions currently set on the sheet. ### Hyperlinks, Defined Names, and Data Validation `Worksheet::GetHyperlinks()` returns a `HyperlinkCollection`. `Add()` takes a target cell or range plus an address and returns the new hyperlink's index, which is used to fetch the `Hyperlink` object for further changes: ```cpp #include "aspose/cells_foss/Hyperlink.h" sheet.GetCells()["A1"].PutValue("Documentation"); int linkIndex = sheet.GetHyperlinks().Add("A1", 1, 1, "https://example.com/docs"); Hyperlink link = sheet.GetHyperlinks()[linkIndex]; link.SetTextToDisplay("Documentation"); link.SetScreenTip("Open the docs site"); ``` `Workbook::GetDefinedNames()` manages named ranges the same way — `Add()` returns an index into the `DefinedNameCollection`: ```cpp #include "aspose/cells_foss/DefinedName.h" int nameIndex = workbook.GetDefinedNames().Add("Total", "=Data!$B$2:$B$3"); DefinedName total = workbook.GetDefinedNames()[nameIndex]; total.SetComment("Sum of tracked expenses"); ``` `Worksheet::GetValidations()` follows the same collection pattern for data validation rules, scoped to a `CellArea`: ```cpp #include "aspose/cells_foss/Validation.h" #include "aspose/cells_foss/CellArea.h" int ruleIndex = sheet.GetValidations().Add(CellArea::CreateCellArea("B2", "B3")); Validation amountRule = sheet.GetValidations()[ruleIndex]; amountRule.SetType(ValidationType::Decimal); amountRule.SetOperator(OperatorType::GreaterThan); amountRule.SetFormula1("0"); amountRule.SetErrorTitle("Invalid Amount"); amountRule.SetErrorMessage("Enter a positive number"); ``` ### Document Properties and Workbook Settings `Workbook::GetDocumentProperties()` exposes the core and extended OOXML metadata fields (title, author, company, manager, and similar), and `Workbook::GetSettings()` controls workbook-level behavior such as the date system: ```cpp #include "aspose/cells_foss/DocumentProperties.h" workbook.GetDocumentProperties().SetCompany("Example Corp"); workbook.GetDocumentProperties().SetManager("Finance Team"); workbook.GetSettings().SetDate1904(false); ``` These values round-trip through save and reload the same way cell content does, which is useful for reports that need consistent metadata across generated files. --- ## Quick Start Aspose.Cells FOSS for C++ is built from source with CMake. Clone the repository and either add it as a subdirectory or pull it in with `FetchContent`: ```bash git clone https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Cpp.git ``` ```cmake cmake_minimum_required(VERSION 3.15) project(MyProject CXX) set(CMAKE_CXX_STANDARD 17) add_subdirectory(path/to/Aspose.Cells-FOSS-for-Cpp) add_executable(MyApp main.cpp) target_link_libraries(MyApp PRIVATE Aspose.Cells.Foss.Cpp) ``` A minimal spreadsheet-management example — create, style, save, and reload: ```cpp #include "aspose/cells_foss/Workbook.h" #include "aspose/cells_foss/Worksheet.h" #include "aspose/cells_foss/Cell.h" using namespace Aspose::Cells_FOSS; int main() { Workbook workbook; Worksheet& sheet = workbook.GetWorksheets()[0]; sheet.SetName("Expenses"); Cells& cells = sheet.GetCells(); cells["A1"].PutValue("Category"); cells["B1"].PutValue("Amount"); cells["A2"].PutValue("Travel"); cells["B2"].PutValue(482.50); cells["A3"].PutValue("Supplies"); cells["B3"].PutValue(129.99); cells["B4"].SetFormula("=SUM(B2:B3)"); workbook.Save("expenses.xlsx"); Workbook loaded("expenses.xlsx"); Cells& loadedCells = loaded.GetWorksheets()["Expenses"].GetCells(); double total = loadedCells["B4"].GetValue().AsDouble(); return 0; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Xlsx | `.xlsx` | ✓ | ✓ | `LoadFormat` and `SaveFormat` both expose a single `Xlsx` value in this release; the `Workbook(path)` and `Workbook(bytes)` constructors load `.xlsx` input, and `Workbook::Save()` writes `.xlsx` output to a path, a stream, or an in-memory buffer. --- ## Open Source & Licensing Aspose.Cells FOSS for C++ is released under the MIT license. Source code is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Cpp), and the library can be used, modified, and redistributed in commercial and open-source projects without runtime fees. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/cpp/) - [API Reference](https://reference.aspose.org/cells/cpp/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Cells FOSS for C++ — Open-Source Excel XLSX Library URL: https://blog.aspose.org/cells/cpp/introducing-cells-foss-cpp/ Aspose.Cells FOSS for C++ is an open-source, MIT-licensed library for creating, loading, editing, and saving Excel XLSX workbooks in native C++ — typed cell values, formulas, styling, data validation, conditional formatting, and page setup, with no Microsoft Excel dependency and no external runtime requirements. --- Product: Aspose.Cells Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/cells/cpp/introducing-cells-foss-cpp/ --- # Introducing Aspose.Cells FOSS for C++ — Open-Source Excel XLSX Library ## Introduction Aspose.Cells FOSS for C++ is an open-source library for creating, loading, editing, and saving Excel `.xlsx` workbooks from native C++ code, without requiring Microsoft Excel or any COM automation. It integrates into a CMake-based build as a source library — there is no external runtime dependency to install or link against beyond the C++ standard library. The library is MIT licensed and targets C++17. It builds with `add_subdirectory` or `FetchContent` from a git clone, since it is not distributed through a package manager such as vcpkg or Conan. The API surface is organized around a `Workbook` that owns a `WorksheetCollection`, worksheets that expose a `Cells` object for cell-level access, and a `Style` facade for fonts, fills, and borders. If you build backend services, report generators, or data-export pipelines in C++ and need to produce or read `.xlsx` files without shelling out to Excel, this library gives you a native way to do it. Aspose.Cells FOSS is also available for .NET, Go, Java, Python, Rust, and TypeScript. The C++ library follows the same approach as the rest of the family: an XLSX-focused API grounded in what is actually implemented, under a permissive license. --- ## What's Included ### Workbook and Worksheet Structure A `Workbook` starts with one worksheet. Additional sheets are created with `WorksheetCollection::Add`, and existing sheets are reached by index or by name through the collection's indexer. Each `Worksheet` exposes its cells through `GetCells()`. ```cpp #include "aspose/cells_foss/Workbook.h" #include "aspose/cells_foss/Worksheet.h" using namespace Aspose::Cells_FOSS; Workbook workbook; workbook.GetWorksheets()[0].SetName("Data"); workbook.GetWorksheets().Add("Summary"); Worksheet& data = workbook.GetWorksheets()["Data"]; data.GetCells()["A1"].PutValue("Product"); data.GetCells()["B1"].PutValue("Price"); ``` ### Cell Values, Formulas, and Number Formats `Cell::PutValue` has overloads for strings, integers, doubles, booleans, and other value kinds, so no manual string conversion is required. `SetFormula` accepts a formula with or without a leading `=` and normalizes it; `GetType` then reports a `CellValueType` of `Formula`. Number formatting is applied through `Style::SetNumberFormat` and affects only the display text returned by `GetDisplayStringValue` — the underlying stored value is unchanged. ```cpp auto& sheet = workbook.GetWorksheets()[0]; auto cell = sheet.GetCells()["B2"]; cell.PutValue(1234.567); auto style = cell.GetStyle(); style.SetNumberFormat("#,##0.00"); cell.SetStyle(style); sheet.GetCells()["B3"].SetFormula("B2*2"); // GetFormula() now returns "=B2*2"; GetType() reports CellValueType::Formula std::cout << cell.GetDisplayStringValue() << std::endl; // "1,234.57" ``` ### Styling with Fonts, Fills, and Borders `Cell::GetStyle()` and `SetStyle()` read and write a `Style` object that groups `Font`, `Borders`, and fill settings. Colors are constructed with `Color::FromArgb`, and fill patterns are set through `FillPattern`. ```cpp Style headerStyle = sheet.GetCells()["A1"].GetStyle(); Font font; font.SetBold(true); font.SetColor(Color::FromArgb(255, 255, 255, 255)); headerStyle.SetFont(font); headerStyle.SetPattern(FillPattern::Solid); headerStyle.SetForegroundColor(Color::FromArgb(255, 34, 120, 212)); sheet.GetCells()["A1"].SetStyle(headerStyle); ``` ### Data Validation and Conditional Formatting `ValidationCollection::Add` scopes a `Validation` rule to a `CellArea`; setting its `ValidationType` to `List` with a `Formula1` value produces an in-cell dropdown. `ConditionalFormattingCollection::Add` creates a formatting group that is scoped with `AddArea` and populated with `AddCondition`, which takes a `FormatConditionType`, an `OperatorType`, and one or two formulas. ```cpp int validationIndex = sheet.GetValidations().Add(CellArea::CreateCellArea("B1", "B3")); auto validation = sheet.GetValidations()[validationIndex]; validation.SetType(ValidationType::List); validation.SetFormula1("\"Open,Closed\""); validation.SetShowError(true); int cfIndex = sheet.GetConditionalFormattings().Add(); auto formatting = sheet.GetConditionalFormattings()[cfIndex]; formatting.AddArea(CellArea::CreateCellArea("C1", "C3")); int conditionIndex = formatting.AddCondition( FormatConditionType::CellValue, OperatorType::Between, "1", "9"); auto condition = formatting[conditionIndex]; auto conditionStyle = condition.GetStyle(); conditionStyle.SetPattern(FillPattern::Solid); conditionStyle.SetForegroundColor(Color::FromArgb(255, 255, 199, 206)); condition.SetStyle(conditionStyle); ``` ### Page Setup and Print Layout `Worksheet::GetPageSetup()` returns a `PageSetup` object controlling paper size, orientation, scaling, print area, and print title rows/columns. Values are validated on assignment — for example, an out-of-range `SetScale` call raises a `CellsException`. ```cpp auto& pageSetup = sheet.GetPageSetup(); pageSetup.SetOrientation(PageOrientationType::Landscape); pageSetup.SetPaperSize(PaperSizeType::PaperA4); pageSetup.SetFitToPagesWide(1); pageSetup.SetFitToPagesTall(3); pageSetup.SetPrintArea("$A$1:$D$20"); pageSetup.SetPrintTitleRows("$1:$2"); ``` --- ## Quick Start Aspose.Cells FOSS for C++ is not distributed through a package manager — clone the repository and add it to your CMake project: ```bash git clone https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Cpp.git ``` Add the library as a subdirectory of your own `CMakeLists.txt` and link against the `aspose_cells_foss` target: ```cmake add_subdirectory(path/to/Aspose.Cells-FOSS-for-Cpp/Aspose.Cells.Foss.Cpp) target_link_libraries(MyApp PRIVATE aspose_cells_foss) ``` Then create, style, and save a workbook: ```cpp #include "aspose/cells_foss/Workbook.h" #include "aspose/cells_foss/Worksheet.h" #include "aspose/cells_foss/Cell.h" #include "aspose/cells_foss/Style.h" #include "aspose/cells_foss/Font.h" #include "aspose/cells_foss/Color.h" using namespace Aspose::Cells_FOSS; int main() { Workbook workbook; Worksheet& sheet = workbook.GetWorksheets()[0]; sheet.SetName("Products"); sheet.GetCells()["A1"].PutValue("Product"); sheet.GetCells()["B1"].PutValue("Price"); sheet.GetCells()["A2"].PutValue("Apple"); sheet.GetCells()["B2"].PutValue(2.99); sheet.GetCells()["A3"].PutValue("Orange"); sheet.GetCells()["B3"].PutValue(1.99); sheet.GetCells()["B4"].SetFormula("SUM(B2:B3)"); Style header = sheet.GetCells()["A1"].GetStyle(); Font font; font.SetBold(true); header.SetFont(font); sheet.GetCells()["A1"].SetStyle(header); workbook.Save("products.xlsx"); return 0; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | XLSX | `.xlsx` | ✓ | ✓ | XLSX is the only format the current release reads and writes. `Workbook`'s file and stream constructors load `.xlsx` data, and `Save` writes it back out; `LoadFormat` and `SaveFormat` enums govern explicit format selection on those calls. --- ## Open Source & Licensing Aspose.Cells FOSS for C++ is MIT licensed. The complete source is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Cpp), and the license permits commercial use, modification, and redistribution. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/cpp/) - [API Reference](https://reference.aspose.org/cells/cpp/) - [Product Page](https://products.aspose.org/cells/cpp/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Cells FOSS for Java URL: https://blog.aspose.org/cells/java/ --- Product: Aspose.Cells Platform: java Page Type: index Canonical URL: https://blog.aspose.org/cells/java/ --- # Aspose.Cells FOSS for Java ## Related Topics - [Core Cell Operations in Aspose.Cells FOSS for Java](https://blog.aspose.org/cells/java/aspose-cells-foss-java-cell-operations/) - [Spreadsheet Management with Aspose.Cells FOSS for Java](https://blog.aspose.org/cells/java/cells-spreadsheet-management-java/) - [Aspose.Cells FOSS for Java Key Features](https://blog.aspose.org/cells/java/java-excel-formulas-styling-api/) - [Introducing Aspose.Cells FOSS for Java](https://blog.aspose.org/cells/java/java-excel-xlsx-library/) --- # Core Cell Operations in Aspose.Cells FOSS for Java URL: https://blog.aspose.org/cells/java/aspose-cells-foss-java-cell-operations/ A deep dive into the core cell API of Aspose.Cells FOSS for Java: typed value storage with putValue(), CellValueType inspection, formula storage, string value access, and round-trip XLSX serialization for all primitive Java types. --- Product: Aspose.Cells Platform: java Page Type: index Canonical URL: https://blog.aspose.org/cells/java/aspose-cells-foss-java-cell-operations/ --- # Core Cell Operations in Aspose.Cells FOSS for Java ## Introduction The `Cell` class is the foundational unit in Aspose.Cells FOSS for Java. It stores typed values, exposes their runtime type through the `CellValueType` enum, persists formula strings for Excel to evaluate, and returns string-formatted representations via `getStringValue()`. This article covers typed value storage, runtime type inspection, formula persistence, and round-trip XLSX serialization with verified code examples. ## Quick Start Add the following Maven dependency to your `pom.xml` to start using Aspose.Cells FOSS: --- ## Core Cell API ### Storing Typed Values with putValue() `Cell.putValue()` accepts six Java types: `String`, `int`, `double`, `boolean`, `LocalDateTime`, and `Object`. Each call sets the cell's internal value and determines the `CellValueType` returned by `cell.getType()`. ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.CellValueType; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; import java.time.LocalDateTime; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); Cell a1 = sheet.getCells().get("A1"); a1.putValue("Revenue"); assert a1.getType() == CellValueType.STRING; Cell b1 = sheet.getCells().get("B1"); b1.putValue(42500.75); assert b1.getType() == CellValueType.NUMBER; Cell c1 = sheet.getCells().get("C1"); c1.putValue(true); assert c1.getType() == CellValueType.BOOLEAN; Cell d1 = sheet.getCells().get("D1"); d1.putValue(LocalDateTime.of(2026, 4, 27, 9, 0, 0)); assert d1.getType() == CellValueType.DATE_TIME; workbook.save("typed.xlsx"); } ``` Blank cells return `CellValueType.BLANK` from `getType()`. Integer values stored with `putValue(int)` round-trip through XLSX serialization without gaining a decimal point — `getStringValue()` returns `"123"` not `"123.0"`. ### Inspecting Values at Runtime `cell.getValue()` returns the raw stored value as `Object`. `cell.getStringValue()` returns a locale-independent string representation suitable for downstream processing or display. Branching on `CellValueType` is the recommended pattern for type-safe value extraction: ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.CellValueType; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); sheet.getCells().get("A1").putValue("Hello"); sheet.getCells().get("B1").putValue(123); sheet.getCells().get("C1").putValue(true); sheet.getCells().get("D1").putValue(12.5d); sheet.getCells().get("G1").setFormula("=B1*2"); Cell b1 = sheet.getCells().get("B1"); if (b1.getType() == CellValueType.NUMBER) { System.out.println("Number: " + b1.getStringValue()); } workbook.save("inspect.xlsx"); } ``` ### Formula Storage Formula strings are stored with `cell.setFormula()`. The stored formula string begins with `=` and follows standard Excel formula syntax. The `getType()` method returns `CellValueType.FORMULA` for formula cells. Aspose.Cells FOSS for Java stores and round-trips formulas in XLSX; the formula is recalculated by Excel on open. ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.CellValueType; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); Cell b1 = sheet.getCells().get("B1"); b1.putValue(100.0); Cell c1 = sheet.getCells().get("C1"); c1.setFormula("=B1*1.2"); assert c1.getType() == CellValueType.FORMULA; workbook.save("formulas.xlsx"); } ``` ### XLSX Round-Trip Fidelity All typed values are preserved across XLSX serialization and reload. Loading an existing `.xlsx` file uses `new Workbook(path)` or `new Workbook(path, options)` with `LoadOptions` to enable repair mode. After reload, `getType()` and `getStringValue()` return the same values as at write time. ```java import com.aspose.cells_foss.LoadIssue; import com.aspose.cells_foss.LoadOptions; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; LoadOptions options = new LoadOptions(); options.setStrictMode(false); options.setTryRepairPackage(true); options.setTryRepairXml(true); try (Workbook workbook = new Workbook("input.xlsx", options)) { if (workbook.getLoadDiagnostics().hasRepairs()) { for (LoadIssue issue : workbook.getLoadDiagnostics().getIssues()) { System.out.println(issue.getMessage()); } } WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); System.out.println(sheet.getCells().get("A1").getStringValue()); workbook.save("output.xlsx"); } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Excel Open XML | .xlsx | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Cells FOSS for Java is released under the MIT license. You are free to use, modify, and distribute it in personal, open-source, and commercial projects without restriction. The source code is available at [github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Java](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Java). --- ## Getting Started - [Installation Guide](https://docs.aspose.org/cells/java/getting-started/installation/) - [Quick Start](https://docs.aspose.org/cells/java/getting-started/quickstart/) - [Developer Guide](https://docs.aspose.org/cells/java/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/java/) - [API Reference](https://reference.aspose.org/cells/java/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for Java — Enterprise Product](https://products.aspose.com/cells/java/) --- # Spreadsheet Management with Aspose.Cells FOSS for Java URL: https://blog.aspose.org/cells/java/cells-spreadsheet-management-java/ A practical walkthrough of creating, loading, modifying, and saving Excel workbooks in Java using Aspose.Cells FOSS. Demonstrates the Workbook, WorksheetCollection, Cells, and Cell APIs with complete code examples. --- Product: Aspose.Cells Platform: java Page Type: index Canonical URL: https://blog.aspose.org/cells/java/cells-spreadsheet-management-java/ --- # Spreadsheet Management with Aspose.Cells FOSS for Java ## Introduction Aspose.Cells FOSS for Java is a pure-Java 17, MIT-licensed library for creating and manipulating Excel `.xlsx` workbooks without any Microsoft Office dependency. This post walks through the most common spreadsheet management operations: creating workbooks, loading files, working with cells, and saving results. ## Quick Start Add the Maven dependency to your `pom.xml` to get started: No license file or API key is required. The library is fully open-source under MIT. --- ### Creating a Workbook The `Workbook()` constructor creates a new, blank workbook with one default sheet: ```java import com.aspose.cells.foss.Workbook; import com.aspose.cells.foss.Worksheet; Workbook workbook = new Workbook(); WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); System.out.println(sheet.getName()); // Sheet1 ``` Use `WorksheetCollection.add(sheetName)` to add named sheets and `removeAt(sheetName)` to remove them: ```java int idx = workbook.getWorksheets().add("Report"); workbook.getWorksheets().get(idx).setName("Report"); workbook.getWorksheets().removeAt("Sheet1"); ``` --- ### Loading an Existing File Pass a file path to `Workbook(fileName)` to open an existing `.xlsx` workbook: ```java Workbook workbook = new Workbook("data/report.xlsx"); System.out.println("Sheets: " + workbook.getWorksheets().getCount()); ``` For input streams (e.g. from a database or HTTP response), use `Workbook(stream)`: ```java try (java.io.InputStream is = new java.io.FileInputStream("data/report.xlsx")) { Workbook workbook = new Workbook(is); } ``` --- ### Reading and Writing Cells `Worksheet.getCells()` returns the `Cells` collection. Access individual cells by name or by zero-based row/column index: ```java import com.aspose.cells.foss.Cells; import com.aspose.cells.foss.Cell; WorksheetCollection sheets = workbook.getWorksheets(); Cells cells = sheets.get(0).getCells(); // Write by cell name cells.get("A1").putValue("Product"); cells.get("B1").putValue("Revenue"); // Write by row/column index cells.get(1, 0).putValue("Widget A"); // A2 cells.get(1, 1).putValue(45000); // B2 // Read back String name = cells.get("A2").getStringValue(); Object rev = cells.get("B2").getValue(); System.out.println(name + ": " + rev); ``` --- ### Setting Formulas Use `Cell.setFormula()` to store a formula string in a cell. The formula is evaluated when the workbook is saved and reloaded: ```java cells.get("B3").setFormula("=SUM(B2:B2)"); System.out.println(cells.get("B3").getFormula()); // =SUM(B2:B2) ``` Formula results are resolved when the workbook is saved and reloaded. --- ### Saving the Workbook `Workbook.save(fileName)` writes the workbook; the format is determined by the file extension (`.xlsx` produces an Excel 2007+ file): ```java workbook.save("output/result.xlsx"); ``` Always wrap large workbooks in try-with-resources to release file handles promptly: ```java try (Workbook workbook = new Workbook("data/input.xlsx")) { workbook.getWorksheets().get(0).getCells().get("A1").putValue("Updated"); workbook.save("data/output.xlsx"); } ``` --- ### What to Explore Next Aspose.Cells FOSS for Java includes APIs for worksheet-level operations beyond cell manipulation: - **Worksheet protection**: `protect()` / `unprotect()` on `Worksheet` - **AutoFilter**: `Worksheet.getAutoFilter()` for programmatic data filtering - **Cell styles**: `Cell.getStyle()` / `setStyle()` with `Style` properties - **Merged cells**: `Cells.merge(firstRow, firstColumn, totalRows, totalColumns)` For a full API walkthrough, see the [developer guide](https://docs.aspose.org/cells/java/developer-guide/) and the [API reference](https://reference.aspose.org/cells/java/). ## Getting Started The examples above cover the most common spreadsheet management tasks in Aspose.Cells FOSS for Java. For a full API walkthrough including validation, charts, and formatting, see the [developer guide](https://docs.aspose.org/cells/java/developer-guide/). ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Cells FOSS for Java Key Features URL: https://blog.aspose.org/cells/java/java-excel-formulas-styling-api/ Explore the key features of Aspose.Cells FOSS for Java: workbook management, typed cell values, style and formatting, data validation, conditional formatting, AutoFilter, and page setup — all under the MIT license with no Office dependency. --- Product: Aspose.Cells Platform: java Page Type: index Canonical URL: https://blog.aspose.org/cells/java/java-excel-formulas-styling-api/ --- # Aspose.Cells FOSS for Java Key Features ## Introduction This post walks through the main feature areas of Aspose.Cells FOSS for Java — a pure-Java 17, MIT-licensed library for creating and manipulating Excel `.xlsx` workbooks. You will learn how to manage workbooks and worksheets, store typed cell values, apply data validation, use AutoFilter, and control page setup — without any Microsoft Office dependency. All code examples use classes from the library's verified API surface. Class and method names shown below exist in version 1.0.0. --- ## Key Features ### Workbook and Worksheet Management The `Workbook` class implements `AutoCloseable` so it integrates cleanly with the Java try-with-resources pattern. You can create a blank workbook, load an existing `.xlsx` file, rename worksheets, add or remove sheets, set the active sheet, and control tab visibility. ```java import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); sheet.setName("Q1 Report"); workbook.getWorksheets().addSheet("Summary"); workbook.save("report.xlsx"); } ``` ### Typed Cell Values and Formulas The `Cell` class accepts typed values via `putValue()` for `String`, `int`, `double`, `boolean`, and `LocalDateTime`. The `getType()` method returns a `CellValueType` enum value — `STRING`, `NUMBER`, `BOOLEAN`, `DATE_TIME`, or `FORMULA` — making it easy to branch on value type without parsing strings. Formula strings are stored with `setFormula()` and will be recalculated by Excel on open. ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.CellValueType; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); Cell a1 = sheet.getCells().get("A1"); a1.putValue("Revenue"); Cell b1 = sheet.getCells().get("B1"); b1.putValue(42500.00); Cell c1 = sheet.getCells().get("C1"); c1.setFormula("=B1*1.2"); // Check type assert b1.getType() == CellValueType.NUMBER; assert c1.getType() == CellValueType.FORMULA; workbook.save("values.xlsx"); } ``` ### Cell Formatting and Styles Formatting is applied through the `Style` object retrieved from `cell.getStyle()` and written back with `cell.setStyle()`. The `Font` sub-object exposes `setBold()` and `setColor()`. `HorizontalAlignment` controls text alignment — `LEFT`, `CENTER`, or `RIGHT`. Custom number formats use Excel format strings via `style.setCustom()`. Row height and column width are adjusted through `getRows().get(n).setHeight()` and `getColumns().get(n).setWidth()`. ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.Style; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); Cell cell = sheet.getCells().get("B1"); cell.putValue(9999.50); Style style = cell.getStyle(); style.getFont().setBold(true); style.setCustom("#,##0.00"); cell.setStyle(style); sheet.getCells().getRows().get(0).setHeight(24.0); sheet.getCells().getColumns().get(1).setWidth(16.0); workbook.save("styled.xlsx"); } ``` ### Data Validation Data validation rules are added through `sheet.getValidations().add()`. Each `Validation` object takes a `ValidationType` (e.g. `WHOLE_NUMBER`, `DECIMAL`, `LIST`) and an `OperatorType` (e.g. `BETWEEN`, `GREATER_THAN`). Formula bounds are stored as strings via `setFormula1()` and `setFormula2()`. ```java import com.aspose.cells_foss.CellArea; import com.aspose.cells_foss.OperatorType; import com.aspose.cells_foss.Validation; import com.aspose.cells_foss.ValidationType; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); int vi = sheet.getValidations().add(new CellArea(1, 0, 10, 0)); Validation validation = sheet.getValidations().get(vi); validation.setType(ValidationType.WHOLE_NUMBER); validation.setOperator(OperatorType.BETWEEN); validation.setFormula1("1"); validation.setFormula2("100"); workbook.save("validated.xlsx"); } ``` ### AutoFilter AutoFilters let end users interactively filter data in Excel without any extra configuration. Call `ws.getAutoFilter().setRange()` with an A1-notation range to activate filter drop-downs on the specified header range. Additional filter columns and custom criteria can be defined through `FilterColumn` and `AutoFilterCustomFilter`. ```java import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); sheet.getCells().get("A1").putValue("Product"); sheet.getCells().get("B1").putValue("Qty"); sheet.getAutoFilter().setRange("A1:B1"); workbook.save("filtered.xlsx"); } ``` ### Page Setup and Worksheet Protection The `PageSetup` class controls paper size, page orientation, and fit-to-page settings for print-ready output. Worksheet protection is applied through `protect()` with a `WorksheetProtectionModel`, allowing specific cells to remain editable while locking the rest. Hyperlinks are managed through `HyperlinkCollection`. --- ## Quick Start Add the following Maven dependency to your `pom.xml` to include Aspose.Cells FOSS in your project: Create a workbook with all major features in under 20 lines: ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.Style; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; public class QuickStart { public static void main(String[] args) { try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); sheet.setName("Sales"); sheet.getCells().get("A1").putValue("Revenue"); Cell b1 = sheet.getCells().get("B1"); b1.putValue(42500.00); Style style = b1.getStyle(); style.getFont().setBold(true); style.setCustom("#,##0.00"); b1.setStyle(style); sheet.getAutoFilter().setRange("A1:B1"); workbook.save("sales.xlsx"); } } } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Excel Open XML | .xlsx | ✓ | ✓ | Saving is currently limited to `.xlsx`. The library stores and round-trips formulas but does not function as a full spreadsheet calculation engine. --- ## Open Source & Licensing Aspose.Cells FOSS for Java is released under the MIT license. You are free to use, modify, and distribute it in personal, open-source, and commercial projects without restriction. The source code is available at [github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Java](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Java). --- ## Getting Started - [Installation Guide](https://docs.aspose.org/cells/java/getting-started/installation/) - [Quick Start](https://docs.aspose.org/cells/java/getting-started/quickstart/) - [Developer Guide](https://docs.aspose.org/cells/java/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/java/) - [API Reference](https://reference.aspose.org/cells/java/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Cells FOSS for Java URL: https://blog.aspose.org/cells/java/java-excel-xlsx-library/ Aspose.Cells FOSS for Java is a pure-Java 17, MIT-licensed library for creating, loading, modifying, and saving Excel .xlsx workbooks. It requires no Microsoft Office or commercial runtime dependency and is built with Maven 3.9+. --- Product: Aspose.Cells Platform: java Page Type: index Canonical URL: https://blog.aspose.org/cells/java/java-excel-xlsx-library/ --- # Introducing Aspose.Cells FOSS for Java ## Introduction Aspose.Cells FOSS for Java is an open-source Java 17 library that enables developers to create, load, modify, and save Excel `.xlsx` workbooks entirely on the JVM — with no Microsoft Office installation, no native libraries, and no commercial Aspose runtime dependency. The public API lives under the `com.aspose.cells_foss` package and is released under the MIT license, making it suitable for personal, open-source, and commercial projects alike. The library ships as a standard Maven artifact and covers the core OOXML spreadsheet object model: workbooks, worksheets, cells, styles, and collections. It is built with Maven 3.9+ and targets Java 17+, integrating naturally into any modern Java build pipeline. Add the dependency to your `pom.xml` and you are ready to generate or process Excel workbooks from a servlet, a batch job, a Lambda function, or any other Java server-side context. --- ## Key Features ### Workbook and Worksheet Management The `Workbook` class is the entry point for all spreadsheet operations. It implements `AutoCloseable` so it integrates cleanly with the try-with-resources pattern. You can create new workbooks, load existing `.xlsx` files, add and remove worksheets, rename sheets with `setName()`, set the active sheet, and control tab visibility. ```java import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; import com.aspose.cells_foss.WorksheetCollection; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); sheet.setName("Sales"); workbook.save("sales.xlsx"); } ``` ### Cell Values and Formulas The `Cell` class supports typed value storage via `putValue()` for strings, integers, doubles, booleans, and `LocalDateTime` values. Formula strings are stored with `setFormula()` and will be recalculated by Excel on open. The value type is exposed through `CellValueType` — `STRING`, `NUMBER`, `BOOLEAN`, `DATE_TIME`, or `FORMULA`. ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); Cell a1 = sheet.getCells().get("A1"); a1.putValue("Revenue"); Cell b1 = sheet.getCells().get("B1"); b1.putValue(12500.75); Cell c1 = sheet.getCells().get("C1"); c1.setFormula("=B1*1.2"); workbook.save("values.xlsx"); } ``` ### Cell Formatting and Styles Formatting is applied through the `Style` class, retrieved from `cell.getStyle()` and written back with `cell.setStyle()`. You can configure bold and colour on the `Font`, apply `HorizontalAlignment`, and set custom number format strings via `style.setCustom()`. Row height and column width are controlled through `getRows().get(n).setHeight()` and `getColumns().get(n).setWidth()`. ```java import com.aspose.cells_foss.Style; import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); Cell cell = sheet.getCells().get("B1"); cell.putValue(9999.5); Style style = cell.getStyle(); style.getFont().setBold(true); style.setCustom("#,##0.00"); cell.setStyle(style); workbook.save("styled.xlsx"); } ``` ### Data Validation and Conditional Formatting Data validation rules are added through `sheet.getValidations().add()`. Each `Validation` object holds a `ValidationType` (e.g., `WHOLE_NUMBER`), an `OperatorType` (e.g., `BETWEEN`), and formula strings for the bounds. Conditional formatting is added through `sheet.getConditionalFormattings().add()`, which returns a `FormatConditionCollection` where you specify cell ranges and conditions. ```java import com.aspose.cells_foss.CellArea; import com.aspose.cells_foss.Validation; import com.aspose.cells_foss.ValidationType; import com.aspose.cells_foss.OperatorType; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); int vi = sheet.getValidations().add(new CellArea(1, 0, 10, 0)); Validation validation = sheet.getValidations().get(vi); validation.setType(ValidationType.WHOLE_NUMBER); validation.setOperator(OperatorType.BETWEEN); validation.setFormula1("1"); validation.setFormula2("100"); workbook.save("validated.xlsx"); } ``` ### AutoFilters and Page Setup AutoFilters are configured by calling `ws.getAutoFilter().setRange()` with an A1-notation range string. The `PageSetup` object controls paper size, orientation, and fit-to-page settings for print-ready output. Worksheet protection is applied through `protect()` with a `WorksheetProtectionModel`. --- ## Quick Start Add the following Maven dependency to your `pom.xml` to include Aspose.Cells FOSS for Java in your project: Create a workbook, populate cells, apply formatting, and save: ```java import com.aspose.cells_foss.Cell; import com.aspose.cells_foss.Style; import com.aspose.cells_foss.Workbook; import com.aspose.cells_foss.Worksheet; public class QuickStart { public static void main(String[] args) { try (Workbook workbook = new Workbook()) { WorksheetCollection sheets = workbook.getWorksheets(); Worksheet sheet = sheets.get(0); sheet.setName("Report"); sheet.getCells().get("A1").putValue("Revenue"); Cell cell = sheet.getCells().get("B1"); cell.putValue(12500.75); Style style = cell.getStyle(); style.getFont().setBold(true); style.setCustom("#,##0.00"); cell.setStyle(style); sheet.getCells().getRows().get(0).setHeight(22.0); sheet.getCells().getColumns().get(1).setWidth(14.5); workbook.save("report.xlsx"); } } } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Excel Open XML | .xlsx | ✓ | ✓ | Saving is currently limited to `.xlsx`. The library stores and round-trips formulas, but it is not a full spreadsheet calculation engine. --- ## Open Source & Licensing Aspose.Cells FOSS for Java is released under the MIT license. You are free to use, modify, and distribute it in personal, open-source, and commercial projects without restriction. The source code is available at [github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Java](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Java). --- ## Getting Started - [Installation Guide](https://docs.aspose.org/cells/java/getting-started/installation/) - [Quick Start](https://docs.aspose.org/cells/java/getting-started/quickstart/) - [Developer Guide](https://docs.aspose.org/cells/java/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/java/) - [API Reference](https://reference.aspose.org/cells/java/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Cells FOSS for .NET URL: https://blog.aspose.org/cells/net/ --- Product: Aspose.Cells Platform: net Page Type: index Canonical URL: https://blog.aspose.org/cells/net/ --- # Aspose.Cells FOSS for .NET ## Related Topics - [Key Features of Aspose.Cells FOSS for .NET](https://blog.aspose.org/cells/net/cells-key-features-net/) - [Formulas and Charts in .NET with Aspose.Cells FOSS](https://blog.aspose.org/cells/net/dotnet-excel-formulas-charts/) - [Introducing Aspose.Cells FOSS for .NET](https://blog.aspose.org/cells/net/dotnet-excel-xlsx-library/) - [Spreadsheet Management in .NET with Aspose.Cells FOSS](https://blog.aspose.org/cells/net/dotnet-xlsx-workbook-worksheet/) --- # Key Features of Aspose.Cells FOSS for .NET URL: https://blog.aspose.org/cells/net/cells-key-features-net/ Explore the key features of Aspose.Cells FOSS for .NET: workbook management, cell data and formulas, styles, conditional formatting, data validation, page setup, worksheet settings, hyperlinks, and named ranges. Free, MIT-licensed, no Office dependency. --- Product: Aspose.Cells Platform: net Page Type: index Canonical URL: https://blog.aspose.org/cells/net/cells-key-features-net/ --- # Key Features of Aspose.Cells FOSS for .NET ## Introduction Aspose.Cells FOSS for .NET is a pure managed-code, MIT-licensed library for reading, writing, and manipulating Excel `.xlsx` workbooks without any Microsoft Office dependency. Installed as the `Aspose.Cells_FOSS` NuGet package, it integrates into any .NET project — console apps, web APIs, background workers, and serverless functions. This post provides a feature-by-feature walkthrough of the public API, showing what is possible and how to invoke each capability from C# code. --- ## Feature Overview ### Workbook and Worksheet Lifecycle The entry point for every operation is the `Workbook` class. Construct one from scratch with `new Workbook()`, or load an existing `.xlsx` with `new Workbook(filePath)` or `new Workbook(stream)`. Navigate sheets via `Workbook.Worksheets`, set `Worksheet.Name` and `Worksheet.VisibilityType`, and persist with `Workbook.Save()`. For damaged files, pass a `LoadOptions` instance with `TryRepairPackage = true` and `TryRepairXml = true`. ```csharp using Aspose.Cells_FOSS; var options = new LoadOptions { TryRepairPackage = true, TryRepairXml = true, }; try { _ = new Workbook("sample.xlsx", options); } catch (WorkbookLoadException exception) { Console.WriteLine(exception.Message); } ``` ### Cell Data and Formulas Write values to cells with `Cell.PutValue()` — overloads accept `string`, `int`, `double`, `decimal`, `bool`, and `DateTime`. Read values back via `Cell.Value`, `Cell.StringValue`, and `Cell.Formula`. Set Excel formulas with the `Cell.Formula` property; the formula string is preserved on save and survives a reload cycle. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].Formula = "=B1*2"; workbook.Save("hello.xlsx"); var loaded = new Workbook("hello.xlsx"); Console.WriteLine(loaded.Worksheets[0].Cells["C1"].Formula); Console.WriteLine(loaded.Worksheets[0].Cells["C1"].StringValue); ``` ### Cell Styling Apply `Style` objects to control font, fill, borders, number format, and alignment. Retrieve the current style with `Cell.GetStyle()`, mutate it, then commit with `Cell.SetStyle()`. For background fills, set `Style.Pattern = FillPattern.Solid` and assign a `Color` to `Style.ForegroundColor`. Use `Cells.Merge()` to span cell ranges. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var cell = workbook.Worksheets[0].Cells["A1"]; cell.PutValue("Styled"); var style = cell.GetStyle(); style.Font.Bold = true; style.Pattern = FillPattern.Solid; style.ForegroundColor = Color.FromArgb(255, 241, 196, 15); cell.SetStyle(style); Console.WriteLine($"{cell.StringValue} / Bold={cell.GetStyle().Font.Bold}"); ``` ### Conditional Formatting Attach conditional formatting rules to cell ranges via `ConditionalFormattingCollection`. Rules support `FormatConditionType.CellValue`, `Expression`, `ColorScale`, `DataBar`, and `IconSet`. Use `OperatorType` to specify comparison operators (`Between`, `Equal`, `GreaterThan`, etc.), assign a `Style` to matched cells, and configure priority and stop-if-true behaviour per rule. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; var cfCollection = sheet.ConditionalFormattings[sheet.ConditionalFormattings.Add()]; cfCollection.AddArea(CellArea.CreateCellArea("A1", "A10")); var rule = cfCollection[cfCollection.AddCondition( FormatConditionType.CellValue, OperatorType.Between, "3", "7")]; var style = rule.Style; style.Pattern = FillPattern.Solid; style.ForegroundColor = Color.FromArgb(255, 255, 199, 206); style.Font.Bold = true; rule.Style = style; workbook.Save("conditional-formatting.xlsx"); ``` ### Data Validation Add input constraints to cells using `Worksheet.Validations`. Supported validation types include `ValidationType.List`, `Decimal`, `Custom`, and more. Configure input prompts (`InputTitle`, `InputMessage`) and error messages (`ErrorTitle`, `ErrorMessage`, `ValidationAlertType`). Use `CellArea.CreateCellArea()` to define the validated range and `Validation.AddArea()` to apply a rule to additional ranges. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Validation Sheet"; var listIdx = sheet.Validations.Add(CellArea.CreateCellArea("A1", "A3")); var listVal = sheet.Validations[listIdx]; listVal.Type = ValidationType.List; listVal.Formula1 = "\"Open,Closed\""; listVal.IgnoreBlank = true; listVal.InCellDropDown = true; listVal.ShowInput = true; listVal.InputTitle = "Status"; listVal.InputMessage = "Pick a status"; listVal.ShowError = true; listVal.ErrorTitle = "Invalid"; listVal.ErrorMessage = "Choose from the list"; workbook.Save("validations-sample.xlsx"); ``` ### Page Setup and Print Options Configure print layout via `Worksheet.PageSetup`. Set margins (`LeftMarginInch`, `RightMarginInch`, `TopMarginInch`, `BottomMarginInch`), `Orientation`, `PaperSize`, scale, print area, title rows and columns, headers and footers, and page breaks. All settings survive a save-load round trip. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Print Sheet"; sheet.Cells["A1"].PutValue("Title"); var pageSetup = sheet.PageSetup; pageSetup.Orientation = PageOrientationType.Landscape; pageSetup.PaperSize = PaperSizeType.PaperA4; pageSetup.PrintArea = "$A$1:$C$10"; pageSetup.PrintTitleRows = "$1:$2"; pageSetup.LeftHeader = "Left Header"; pageSetup.CenterFooter = "Center Footer"; pageSetup.PrintGridlines = true; pageSetup.CenterHorizontally = true; workbook.Save("page-setup-sample.xlsx"); ``` ### Worksheet Settings and Protection Control per-sheet display with `Worksheet.ShowGridlines`, `ShowRowColumnHeaders`, `ShowZeros`, `RightToLeft`, `Zoom`, and `TabColor`. Protect sheets with `Worksheet.Protect()` and configure fine-grained `Protection` flags (`Objects`, `FormatCells`, `InsertRows`, `AutoFilter`, `SelectLockedCells`). Manage row height, column width, hidden rows/columns, and merged regions via `Cells.Rows`, `Cells.Columns`, and `Cells.Merge()`. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var layout = workbook.Worksheets[0]; layout.Name = "Layout"; layout.VisibilityType = VisibilityType.Hidden; layout.TabColor = Color.FromArgb(255, 34, 68, 102); layout.ShowGridlines = false; layout.Zoom = 85; layout.Protect(); layout.Protection.FormatCells = true; layout.Protection.InsertRows = true; layout.Cells["A1"].PutValue("Merged"); layout.Cells.Rows[1].Height = 22.5d; layout.Cells.Columns[0].Width = 18.25d; layout.Cells.Merge(0, 0, 2, 2); workbook.Save("worksheet-settings-sample.xlsx"); ``` ### Hyperlinks and Named Ranges Add external, internal, and `mailto:` hyperlinks via `HyperlinkCollection.Add()`. Set `Hyperlink.TextToDisplay` and `Hyperlink.ScreenTip` for user-visible labels. Define named ranges at workbook or sheet scope using `DefinedNameCollection.Add()` — named ranges serve as stable formula anchors and chart data sources that survive file reload. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Docs"); var link = sheet.Hyperlinks[sheet.Hyperlinks.Add("A1", 1, 1, "https://example.com/docs")]; link.TextToDisplay = "Docs"; link.ScreenTip = "External documentation"; var name = workbook.DefinedNames[workbook.DefinedNames.Add("PrimaryRange", "='Sheet1'!$A$1:$D$5")]; name.Comment = "Primary data range"; workbook.Save("hyperlinks-names.xlsx"); Console.WriteLine("Hyperlinks: " + sheet.Hyperlinks.Count); Console.WriteLine("Defined names: " + workbook.DefinedNames.Count); ``` --- ## Quick Start ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].Formula = "=B1*2"; workbook.Save("output.xlsx"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Xlsx | .xlsx | ✓ | ✓ | | Auto | (various) | ✓ | — | --- ## Open Source & Licensing Aspose.Cells FOSS for .NET is published under the MIT license and distributed via NuGet as `Aspose.Cells_FOSS`. It is suitable for open-source and commercial projects alike. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/net/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/net/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/net/) - [API Reference](https://reference.aspose.org/cells/net/) ## Related Resources - [Aspose.Cells for .NET Enterprise](https://products.aspose.com/cells/) --- # Formulas and Charts in .NET with Aspose.Cells FOSS URL: https://blog.aspose.org/cells/net/dotnet-excel-formulas-charts/ Build Excel formulas and charts programmatically in .NET with Aspose.Cells FOSS: Cell.Formula round-trips, Worksheet.Charts, ChartCollection.Add(), and the full ChartType enum, alongside workbook management, styles, conditional formatting, data validation, and page setup. Free, MIT-licensed, no Office dependency. --- Product: Aspose.Cells Platform: net Page Type: index Canonical URL: https://blog.aspose.org/cells/net/dotnet-excel-formulas-charts/ --- # Formulas and Charts in .NET with Aspose.Cells FOSS ## Introduction Aspose.Cells FOSS for .NET is a pure managed-code, MIT-licensed library for reading, writing, and manipulating Excel `.xlsx` workbooks without any Microsoft Office dependency. Installed as the `Aspose.Cells_FOSS` NuGet package, it integrates into any .NET project — console apps, web APIs, background workers, and serverless functions. This post provides a feature-by-feature walkthrough of the public API, showing what is possible and how to invoke each capability from C# code. --- ## Feature Overview ### Workbook and Worksheet Lifecycle The entry point for every operation is the `Workbook` class. Construct one from scratch with `new Workbook()`, or load an existing `.xlsx` with `new Workbook(filePath)` or `new Workbook(stream)`. Navigate sheets via `Workbook.Worksheets`, set `Worksheet.Name` and `Worksheet.VisibilityType`, and persist with `Workbook.Save()`. For damaged files, pass a `LoadOptions` instance with `TryRepairPackage = true` and `TryRepairXml = true`. ```csharp using Aspose.Cells_FOSS; var options = new LoadOptions { TryRepairPackage = true, TryRepairXml = true, }; try { _ = new Workbook("sample.xlsx", options); } catch (WorkbookLoadException exception) { Console.WriteLine(exception.Message); } ``` ### Cell Data and Formulas Write values to cells with `Cell.PutValue()` — overloads accept `string`, `int`, `double`, `decimal`, `bool`, and `DateTime`. Read values back via `Cell.Value`, `Cell.StringValue`, and `Cell.Formula`. Set Excel formulas with the `Cell.Formula` property; the formula string is preserved on save and survives a reload cycle. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].Formula = "=B1*2"; workbook.Save("hello.xlsx"); var loaded = new Workbook("hello.xlsx"); Console.WriteLine(loaded.Worksheets[0].Cells["C1"].Formula); Console.WriteLine(loaded.Worksheets[0].Cells["C1"].StringValue); ``` ### Charts Add charts to a worksheet through `Worksheet.Charts`, a `ChartCollection`. Call `ChartCollection.Add(ChartType, dataRange, upperLeftRow, upperLeftColumn, lowerRightRow, lowerRightColumn)` to insert a chart bound to a cell range, then index back into the collection to get the `Chart` instance and set its `Name`. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Charts"; for (var month = 1; month <= 12; month++) { sheet.Cells[month, 0].PutValue("Month " + month); sheet.Cells[month, 1].PutValue(month * 1000); } var chartIndex = sheet.Charts.Add(ChartType.Column, "Charts!$B$1:$B$13", 0, 4, 18, 8); var chart = sheet.Charts[chartIndex]; chart.Name = "Revenue"; workbook.Save("charts-sample.xlsx"); ``` `ChartType` covers the standard Excel chart families — `Column`, `Bar`, `Line`, `Area`, `Pie`, `Doughnut`, `Scatter`, `Bubble`, and `Radar` — selected by passing the corresponding enum member as the first argument to `Add()`. ### Cell Styling Apply `Style` objects to control font, fill, borders, number format, and alignment. Retrieve the current style with `Cell.GetStyle()`, mutate it, then commit with `Cell.SetStyle()`. For background fills, set `Style.Pattern = FillPattern.Solid` and assign a `Color` to `Style.ForegroundColor`. Use `Cells.Merge()` to span cell ranges. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var cell = workbook.Worksheets[0].Cells["A1"]; cell.PutValue("Styled"); var style = cell.GetStyle(); style.Font.Bold = true; style.Pattern = FillPattern.Solid; style.ForegroundColor = Color.FromArgb(255, 241, 196, 15); cell.SetStyle(style); Console.WriteLine($"{cell.StringValue} / Bold={cell.GetStyle().Font.Bold}"); ``` ### Conditional Formatting Attach conditional formatting rules to cell ranges via `ConditionalFormattingCollection`. Rules support `FormatConditionType.CellValue`, `Expression`, `ColorScale`, `DataBar`, and `IconSet`. Use `OperatorType` to specify comparison operators (`Between`, `Equal`, `GreaterThan`, etc.), assign a `Style` to matched cells, and configure priority and stop-if-true behaviour per rule. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; var cfCollection = sheet.ConditionalFormattings[sheet.ConditionalFormattings.Add()]; cfCollection.AddArea(CellArea.CreateCellArea("A1", "A10")); var rule = cfCollection[cfCollection.AddCondition( FormatConditionType.CellValue, OperatorType.Between, "3", "7")]; var style = rule.Style; style.Pattern = FillPattern.Solid; style.ForegroundColor = Color.FromArgb(255, 255, 199, 206); style.Font.Bold = true; rule.Style = style; workbook.Save("conditional-formatting.xlsx"); ``` ### Data Validation Add input constraints to cells using `Worksheet.Validations`. Supported validation types include `ValidationType.List`, `Decimal`, `Custom`, and more. Configure input prompts (`InputTitle`, `InputMessage`) and error messages (`ErrorTitle`, `ErrorMessage`, `ValidationAlertType`). Use `CellArea.CreateCellArea()` to define the validated range and `Validation.AddArea()` to apply a rule to additional ranges. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Validation Sheet"; var listIdx = sheet.Validations.Add(CellArea.CreateCellArea("A1", "A3")); var listVal = sheet.Validations[listIdx]; listVal.Type = ValidationType.List; listVal.Formula1 = "\"Open,Closed\""; listVal.IgnoreBlank = true; listVal.InCellDropDown = true; listVal.ShowInput = true; listVal.InputTitle = "Status"; listVal.InputMessage = "Pick a status"; listVal.ShowError = true; listVal.ErrorTitle = "Invalid"; listVal.ErrorMessage = "Choose from the list"; workbook.Save("validations-sample.xlsx"); ``` ### Page Setup and Print Options Configure print layout via `Worksheet.PageSetup`. Set margins (`LeftMarginInch`, `RightMarginInch`, `TopMarginInch`, `BottomMarginInch`), `Orientation`, `PaperSize`, scale, print area, title rows and columns, headers and footers, and page breaks. All settings survive a save-load round trip. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Print Sheet"; sheet.Cells["A1"].PutValue("Title"); var pageSetup = sheet.PageSetup; pageSetup.Orientation = PageOrientationType.Landscape; pageSetup.PaperSize = PaperSizeType.PaperA4; pageSetup.PrintArea = "$A$1:$C$10"; pageSetup.PrintTitleRows = "$1:$2"; pageSetup.LeftHeader = "Left Header"; pageSetup.CenterFooter = "Center Footer"; pageSetup.PrintGridlines = true; pageSetup.CenterHorizontally = true; workbook.Save("page-setup-sample.xlsx"); ``` ### Worksheet Settings and Protection Control per-sheet display with `Worksheet.ShowGridlines`, `ShowRowColumnHeaders`, `ShowZeros`, `RightToLeft`, `Zoom`, and `TabColor`. Protect sheets with `Worksheet.Protect()` and configure fine-grained `Protection` flags (`Objects`, `FormatCells`, `InsertRows`, `AutoFilter`, `SelectLockedCells`). Manage row height, column width, hidden rows/columns, and merged regions via `Cells.Rows`, `Cells.Columns`, and `Cells.Merge()`. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var layout = workbook.Worksheets[0]; layout.Name = "Layout"; layout.VisibilityType = VisibilityType.Hidden; layout.TabColor = Color.FromArgb(255, 34, 68, 102); layout.ShowGridlines = false; layout.Zoom = 85; layout.Protect(); layout.Protection.FormatCells = true; layout.Protection.InsertRows = true; layout.Cells["A1"].PutValue("Merged"); layout.Cells.Rows[1].Height = 22.5d; layout.Cells.Columns[0].Width = 18.25d; layout.Cells.Merge(0, 0, 2, 2); workbook.Save("worksheet-settings-sample.xlsx"); ``` ### Hyperlinks and Named Ranges Add external, internal, and `mailto:` hyperlinks via `HyperlinkCollection.Add()`. Set `Hyperlink.TextToDisplay` and `Hyperlink.ScreenTip` for user-visible labels. Define named ranges at workbook or sheet scope using `DefinedNameCollection.Add()` — named ranges serve as stable formula anchors and chart data sources that survive file reload. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Docs"); var link = sheet.Hyperlinks[sheet.Hyperlinks.Add("A1", 1, 1, "https://example.com/docs")]; link.TextToDisplay = "Docs"; link.ScreenTip = "External documentation"; var name = workbook.DefinedNames[workbook.DefinedNames.Add("PrimaryRange", "='Sheet1'!$A$1:$D$5")]; name.Comment = "Primary data range"; workbook.Save("hyperlinks-names.xlsx"); Console.WriteLine("Hyperlinks: " + sheet.Hyperlinks.Count); Console.WriteLine("Defined names: " + workbook.DefinedNames.Count); ``` --- ## Quick Start ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].Formula = "=B1*2"; workbook.Save("output.xlsx"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Xlsx | .xlsx | ✓ | ✓ | | Auto | (various) | ✓ | — | --- ## Open Source & Licensing Aspose.Cells FOSS for .NET is published under the MIT license and distributed via NuGet as `Aspose.Cells_FOSS`. It is suitable for open-source and commercial projects alike. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/net/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/net/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/net/) - [API Reference](https://reference.aspose.org/cells/net/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for .NET — Enterprise Product](https://products.aspose.com/cells/net/) --- # Introducing Aspose.Cells FOSS for .NET URL: https://blog.aspose.org/cells/net/dotnet-excel-xlsx-library/ Aspose.Cells FOSS for .NET is a free, MIT-licensed open-source library for creating, reading, modifying, and saving Excel .xlsx workbooks in pure managed code, with no Microsoft Office installation required. Install with a single NuGet command and work with cells, formulas, styles, conditional formatting, data validation, and hyperlinks. --- Product: Aspose.Cells Platform: net Page Type: index Canonical URL: https://blog.aspose.org/cells/net/dotnet-excel-xlsx-library/ --- # Introducing Aspose.Cells FOSS for .NET ## Introduction Aspose.Cells FOSS for .NET is a free, MIT-licensed open-source library that enables .NET developers to create, load, edit, and save Excel `.xlsx` workbooks without any Microsoft Office installation or native COM dependency. It is distributed as the `Aspose.Cells_FOSS` NuGet package and runs on Windows, macOS, Linux, Docker, and serverless environments. The library covers the full workbook lifecycle: constructing `Workbook` objects from scratch or from existing `.xlsx` files, navigating worksheets, reading and writing cell values of multiple data types, evaluating formulas, applying `Style` objects, setting up conditional formatting rules, adding data validations, managing hyperlinks and named ranges, and configuring page setup for print. All operations work against `.xlsx` files with no runtime dependency beyond the NuGet package itself. Whether you are building a financial reporting API, a data export pipeline, or an automated test harness that validates spreadsheet output, Aspose.Cells FOSS for .NET provides a stable, audit-friendly foundation licensed for both open-source and commercial use. --- ## Key Features ### Workbook and Worksheet Management Create workbooks from scratch or load existing `.xlsx` files using `new Workbook()` or `new Workbook(filePath)`. Access worksheets by index or name via `WorksheetCollection`, add and rename sheets, set visibility, and save back to a file path or `Stream` with `Workbook.Save()`. Configure load-time repair with `LoadOptions` (`TryRepairPackage`, `TryRepairXml`) to handle malformed files gracefully. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].Formula = "=B1*2"; workbook.Save("hello.xlsx"); var loaded = new Workbook("hello.xlsx"); Console.WriteLine(loaded.Worksheets[0].Cells["C1"].Formula); Console.WriteLine(loaded.Worksheets[0].Cells["C1"].StringValue); ``` ### Cell Styling and Formatting Apply `Style` objects to cells for font properties, fill color, borders, number formats, and alignment. Read the current style with `Cell.GetStyle()`, modify it, and commit with `Cell.SetStyle()`. The styling API uses `FillPattern.Solid` with `ForegroundColor` for background fills, and `Style.Font.Bold` for font weight control. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var cell = workbook.Worksheets[0].Cells["A1"]; cell.PutValue("Styled"); var style = cell.GetStyle(); style.Font.Bold = true; style.Pattern = FillPattern.Solid; style.ForegroundColor = Color.FromArgb(255, 241, 196, 15); cell.SetStyle(style); Console.WriteLine($"{cell.StringValue} / Bold={cell.GetStyle().Font.Bold}"); ``` ### Conditional Formatting Add conditional formatting rules to any cell range via `ConditionalFormattingCollection`. Supported rule types include `FormatConditionType.CellValue`, `Expression`, `ColorScale`, `DataBar`, and `IconSet`. Use `OperatorType` values such as `Between`, `Equal`, and `GreaterThan` to define conditions, then assign a `Style` to matched cells for visual highlighting. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; var cfCollection = sheet.ConditionalFormattings[sheet.ConditionalFormattings.Add()]; cfCollection.AddArea(CellArea.CreateCellArea("A1", "A10")); var rule = cfCollection[cfCollection.AddCondition( FormatConditionType.CellValue, OperatorType.Between, "3", "7")]; var style = rule.Style; style.Pattern = FillPattern.Solid; style.ForegroundColor = Color.FromArgb(255, 255, 199, 206); style.Font.Bold = true; rule.Style = style; workbook.Save("conditional-formatting.xlsx"); ``` ### Data Validation Define list, decimal, and custom validation rules on any cell range using `Worksheet.Validations`. Each `Validation` instance supports `ValidationType`, `OperatorType`, formula bounds, input prompts, error messages, and `ValidationAlertType` for warning versus stop alerts. Validations survive a full save-load cycle. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Validation Sheet"; var listIdx = sheet.Validations.Add(CellArea.CreateCellArea("A1", "A3")); var listVal = sheet.Validations[listIdx]; listVal.Type = ValidationType.List; listVal.Formula1 = "\"Open,Closed\""; listVal.IgnoreBlank = true; listVal.InCellDropDown = true; listVal.ShowInput = true; listVal.InputTitle = "Status"; listVal.InputMessage = "Pick a status"; workbook.Save("validations-sample.xlsx"); ``` ### Hyperlinks and Named Ranges Add external URLs, internal cell references, and `mailto:` links via `HyperlinkCollection.Add()`. Set `Hyperlink.TextToDisplay` and `Hyperlink.ScreenTip` for user-visible labels. Define workbook-scoped or sheet-scoped named ranges with `DefinedNameCollection.Add()` to create stable anchors for formulas and chart data sources. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Docs"); var link = sheet.Hyperlinks[sheet.Hyperlinks.Add("A1", 1, 1, "https://example.com/docs")]; link.TextToDisplay = "Docs"; link.ScreenTip = "External documentation"; var name = workbook.DefinedNames[workbook.DefinedNames.Add("PrimaryRange", "='Sheet1'!$A$1:$D$5")]; name.Comment = "Primary data range"; workbook.Save("hyperlinks-names.xlsx"); Console.WriteLine("Hyperlinks: " + sheet.Hyperlinks.Count); Console.WriteLine("Defined names: " + workbook.DefinedNames.Count); ``` --- ## Quick Start Install the package: Create a workbook, write mixed-type values and a formula, save to `.xlsx`, then reload and verify: ```csharp using Aspose.Cells_FOSS; var outputPath = Path.Combine(AppContext.BaseDirectory, "cell-data-roundtrip.xlsx"); var timestamp = new DateTime(2024, 5, 6, 7, 8, 9, DateTimeKind.Utc); var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].PutValue(true); sheet.Cells["D1"].PutValue(12.5m); sheet.Cells["E1"].PutValue(timestamp); sheet.Cells["F1"].PutValue(10); sheet.Cells["G1"].PutValue(20); sheet.Cells["G1"].Formula = "=F1*2"; workbook.Save(outputPath); var loaded = new Workbook(outputPath); var loadedSheet = loaded.Worksheets[0]; Console.WriteLine(loadedSheet.Cells["A1"].StringValue); Console.WriteLine(loadedSheet.Cells["G1"].Formula + " -> " + loadedSheet.Cells["G1"].StringValue); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Xlsx | .xlsx | ✓ | ✓ | | Auto | (various) | ✓ | — | --- ## Open Source & Licensing Aspose.Cells FOSS for .NET is published under the MIT license. The package is distributed via NuGet as `Aspose.Cells_FOSS`. MIT licensing permits use in both open-source and commercial projects with no royalties or restrictions on redistribution. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/net/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/net/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/net/) - [API Reference](https://reference.aspose.org/cells/net/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Spreadsheet Management in .NET with Aspose.Cells FOSS URL: https://blog.aspose.org/cells/net/dotnet-xlsx-workbook-worksheet/ A practical guide to spreadsheet management with Aspose.Cells FOSS for .NET: loading and saving .xlsx workbooks, worksheet settings, page setup and print configuration, data validation, and protected worksheets — all with verified C# code examples. --- Product: Aspose.Cells Platform: net Page Type: index Canonical URL: https://blog.aspose.org/cells/net/dotnet-xlsx-workbook-worksheet/ --- # Spreadsheet Management in .NET with Aspose.Cells FOSS ## Introduction Aspose.Cells FOSS for .NET provides a comprehensive API for managing Excel `.xlsx` workbooks entirely in managed code, with no Microsoft Office dependency. The `Aspose.Cells_FOSS` NuGet package exposes a public surface covering the complete workbook lifecycle — from loading (including repair of damaged files) through cell operations, worksheet configuration, print setup, and save. This guide focuses on the spreadsheet management layer: how workbooks are loaded and saved, how worksheet display and protection settings are configured, how page setup is controlled for print output, and how data validation rules are defined. All code examples use verified API members from the library's public surface. --- ## Loading Workbooks ### Standard and Repair Loading Load an existing `.xlsx` file by passing the file path to `new Workbook(filePath)`. For files that may be damaged or contain structural errors, pass a `LoadOptions` instance with `TryRepairPackage = true` and `TryRepairXml = true`. If the file cannot be parsed even with repair enabled, a `WorkbookLoadException` is thrown. ```csharp using Aspose.Cells_FOSS; var options = new LoadOptions { TryRepairPackage = true, TryRepairXml = true, }; try { _ = new Workbook("sample.xlsx", options); } catch (WorkbookLoadException exception) { Console.WriteLine(exception.Message); } ``` ### Round-Trip Fidelity After loading, cell values of all supported types — `string`, `int`, `double`, `decimal`, `bool`, `DateTime` — are preserved on save. Formulas set via `Cell.Formula` are stored as formula strings and remain intact across a save-load cycle. ```csharp using Aspose.Cells_FOSS; var outputPath = Path.Combine(AppContext.BaseDirectory, "cell-data-roundtrip.xlsx"); var timestamp = new DateTime(2024, 5, 6, 7, 8, 9, DateTimeKind.Utc); var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].PutValue(true); sheet.Cells["D1"].PutValue(12.5m); sheet.Cells["E1"].PutValue(timestamp); sheet.Cells["F1"].PutValue(10); sheet.Cells["G1"].PutValue(20); sheet.Cells["G1"].Formula = "=F1*2"; workbook.Save(outputPath); var loaded = new Workbook(outputPath); var loadedSheet = loaded.Worksheets[0]; Console.WriteLine(loadedSheet.Cells["A1"].StringValue); Console.WriteLine(loadedSheet.Cells["G1"].Formula + " -> " + loadedSheet.Cells["G1"].StringValue); ``` --- ## Worksheet Settings ### Display, Visibility, and Layout Each `Worksheet` exposes display settings via `ShowGridlines`, `ShowRowColumnHeaders`, `ShowZeros`, `RightToLeft`, `Zoom`, and `TabColor`. Set `VisibilityType` to `VisibilityType.Hidden` to hide a sheet from the tab bar. Control row height and column width through `Cells.Rows[index].Height` and `Cells.Columns[index].Width`. Use `Cells.Merge(rowIndex, colIndex, rowSpan, colSpan)` to merge a block of cells into one logical cell. ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var layout = workbook.Worksheets[0]; layout.Name = "Layout"; layout.VisibilityType = VisibilityType.Hidden; layout.TabColor = Color.FromArgb(255, 34, 68, 102); layout.ShowGridlines = false; layout.ShowRowColumnHeaders = false; layout.ShowZeros = false; layout.RightToLeft = true; layout.Zoom = 85; layout.Protect(); layout.Protection.Objects = true; layout.Protection.Scenarios = true; layout.Protection.FormatCells = true; layout.Protection.InsertRows = true; layout.Protection.AutoFilter = true; layout.Protection.SelectLockedCells = true; layout.Protection.SelectUnlockedCells = true; layout.Cells["A1"].PutValue("Merged"); layout.Cells["C4"].PutValue(99); layout.Cells.Rows[1].Height = 22.5d; layout.Cells.Rows[3].IsHidden = true; layout.Cells.Columns[0].Width = 18.25d; layout.Cells.Columns[2].IsHidden = true; layout.Cells.Merge(0, 0, 2, 2); var visibleIndex = workbook.Worksheets.Add("Visible"); var visibleSheet = workbook.Worksheets[visibleIndex]; visibleSheet.Cells["A1"].PutValue("Visible"); workbook.Worksheets.ActiveSheetName = "Visible"; workbook.Save("worksheet-settings-sample.xlsx"); var loaded = new Workbook("worksheet-settings-sample.xlsx"); var loadedLayout = loaded.Worksheets["Layout"]; Console.WriteLine("Active sheet: " + loaded.Worksheets.ActiveSheetName); Console.WriteLine("Layout visibility: " + loadedLayout.VisibilityType); Console.WriteLine("Merged regions: " + loadedLayout.Cells.MergedCells.Count); ``` --- ## Page Setup for Print The `Worksheet.PageSetup` object controls all print-layout parameters. Configure margins, `Orientation` (`PageOrientationType.Landscape` or `Portrait`), `PaperSize`, scale, `PrintArea`, `PrintTitleRows`, `PrintTitleColumns`, header and footer text, gridlines, centering, and page breaks. All settings survive a save-load cycle. ```csharp using Aspose.Cells_FOSS; var outputPath = Path.Combine(AppContext.BaseDirectory, "page-setup-sample.xlsx"); var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Print Sheet"; sheet.Cells["A1"].PutValue("Title"); sheet.Cells["C10"].PutValue(42); var pageSetup = sheet.PageSetup; pageSetup.LeftMarginInch = 0.25d; pageSetup.RightMarginInch = 0.4d; pageSetup.TopMarginInch = 0.5d; pageSetup.BottomMarginInch = 0.6d; pageSetup.HeaderMarginInch = 0.2d; pageSetup.FooterMarginInch = 0.22d; pageSetup.Orientation = PageOrientationType.Landscape; pageSetup.PaperSize = PaperSizeType.PaperA4; pageSetup.FirstPageNumber = 3; pageSetup.Scale = 95; pageSetup.FitToPagesWide = 1; pageSetup.FitToPagesTall = 2; pageSetup.PrintArea = "$A$1:$C$10"; pageSetup.PrintTitleRows = "$1:$2"; pageSetup.PrintTitleColumns = "$A:$B"; pageSetup.LeftHeader = "Left Header"; pageSetup.CenterHeader = "Center Header"; pageSetup.RightHeader = "Right Header"; pageSetup.LeftFooter = "Left Footer"; pageSetup.CenterFooter = "Center Footer"; pageSetup.RightFooter = "Right Footer"; pageSetup.PrintGridlines = true; pageSetup.PrintHeadings = true; pageSetup.CenterHorizontally = true; pageSetup.CenterVertically = true; pageSetup.AddHorizontalPageBreak(4); pageSetup.AddHorizontalPageBreak(7); pageSetup.AddVerticalPageBreak(2); workbook.Save(outputPath); var loaded = new Workbook(outputPath); var loadedPageSetup = loaded.Worksheets[0].PageSetup; Console.WriteLine("Orientation: " + loadedPageSetup.Orientation); Console.WriteLine("Paper size: " + loadedPageSetup.PaperSize); Console.WriteLine("Print area: " + loadedPageSetup.PrintArea); ``` --- ## Data Validation `Worksheet.Validations` manages all input-constraint rules on a sheet. Call `Validations.Add(CellArea)` to register a rule, then configure its `Type` (`ValidationType.List`, `Decimal`, `Custom`), `Operator`, formula bounds, alert style (`ValidationAlertType.Warning` or `Stop`), and prompt messages. ```csharp using Aspose.Cells_FOSS; var outputPath = Path.Combine(AppContext.BaseDirectory, "validations-sample.xlsx"); var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Name = "Validation Sheet"; sheet.Cells["A1"].PutValue("Open"); sheet.Cells["B2"].PutValue(5); sheet.Cells["C3"].PutValue(7); sheet.Cells["E2"].PutValue(8); sheet.Cells["G1"].PutValue("ABCDE"); var listValidationIndex = sheet.Validations.Add(CellArea.CreateCellArea("A1", "A3")); var listValidation = sheet.Validations[listValidationIndex]; listValidation.Type = ValidationType.List; listValidation.Formula1 = "\"Open,Closed\""; listValidation.IgnoreBlank = true; listValidation.InCellDropDown = true; listValidation.ShowInput = true; listValidation.InputTitle = "Status"; listValidation.InputMessage = "Pick a status"; listValidation.ShowError = true; listValidation.ErrorTitle = "Invalid"; listValidation.ErrorMessage = "Choose from the list"; var decimalValidationIndex = sheet.Validations.Add(CellArea.CreateCellArea("B2", "C3")); var decimalValidation = sheet.Validations[decimalValidationIndex]; decimalValidation.Type = ValidationType.Decimal; decimalValidation.Operator = OperatorType.Between; decimalValidation.Formula1 = "1.5"; decimalValidation.Formula2 = "9.5"; decimalValidation.ErrorTitle = "Range"; decimalValidation.ErrorMessage = "Enter 1.5-9.5"; decimalValidation.ShowError = true; decimalValidation.AddArea(CellArea.CreateCellArea("E2", "E3")); var customValidationIndex = sheet.Validations.Add(CellArea.CreateCellArea("G1", "G1")); var customValidation = sheet.Validations[customValidationIndex]; customValidation.Type = ValidationType.Custom; customValidation.AlertStyle = ValidationAlertType.Warning; customValidation.Formula1 = "LEN(G1)<=5"; customValidation.ShowInput = true; customValidation.InputTitle = "Code"; customValidation.InputMessage = "Up to 5 chars"; workbook.Save(outputPath); var loaded = new Workbook(outputPath); var loadedSheet = loaded.Worksheets["Validation Sheet"]; Console.WriteLine("Validation count: " + loadedSheet.Validations.Count); ``` --- ## Quick Start ```csharp using Aspose.Cells_FOSS; var workbook = new Workbook(); var sheet = workbook.Worksheets[0]; sheet.Cells["A1"].PutValue("Hello"); sheet.Cells["B1"].PutValue(123); sheet.Cells["C1"].Formula = "=B1*2"; workbook.Save("output.xlsx"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Xlsx | .xlsx | ✓ | ✓ | | Auto | (various) | ✓ | — | --- ## Open Source & Licensing Aspose.Cells FOSS for .NET is published under the MIT license and distributed via NuGet as `Aspose.Cells_FOSS`. It is suitable for both open-source and commercial use. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/net/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/net/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/net/) - [API Reference](https://reference.aspose.org/cells/net/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Cells FOSS for Python URL: https://blog.aspose.org/cells/python/ --- Product: Aspose.Cells Platform: python Page Type: index Canonical URL: https://blog.aspose.org/cells/python/ --- # Aspose.Cells FOSS for Python ## Related Topics - [How to Create Excel Charts from Python Data Using Aspose.Cells FOSS](https://blog.aspose.org/cells/python/aspose-cells-foss-python-excel-chart-tutorial/) - [Create Hyperlinks in Excel Files Using Aspose.Cells FOSS for Python](https://blog.aspose.org/cells/python/aspose-cells-foss-python-excel-hyperlinks/) - [Spreadsheet Management in Python with Aspose.Cells FOSS](https://blog.aspose.org/cells/python/cells-spreadsheet-management-python/) - [Introducing Aspose.Cells FOSS for Python](https://blog.aspose.org/cells/python/python-excel-xlsx-library/) --- # How to Create Excel Charts from Python Data Using Aspose.Cells FOSS URL: https://blog.aspose.org/cells/python/aspose-cells-foss-python-excel-chart-tutorial/ Learn how to build column, line, and bar charts inside Excel workbooks from Python using Aspose.Cells FOSS — with named data series, category labels, and legend control. No Microsoft Office required. --- Product: Aspose.Cells Platform: python Page Type: index Canonical URL: https://blog.aspose.org/cells/python/aspose-cells-foss-python-excel-chart-tutorial/ --- # How to Create Excel Charts from Python Data Using Aspose.Cells FOSS ## Introduction This guide shows how to create Excel charts from Python data using Aspose.Cells FOSS — a pure-Python, MIT-licensed library for building `.xlsx` workbooks without Microsoft Office. You will learn how to build column, line, and pie charts with named data series, category labels, and legend control. Automated reporting pipelines often need charts embedded in Excel workbooks, such as quarterly summaries, dashboards, or operational metrics. Aspose.Cells FOSS provides a chart API that uses one method per chart type (`add_bar`, `add_line`, `add_pie`) and keyword arguments for series configuration. --- ## Quick Start Run the following command to install the `aspose-cells-foss` package from PyPI: Import the `Workbook` and `Cell` classes at the top of your script: ```python from aspose.cells_foss import Workbook, Cell ``` Charts are accessed via `ws.charts`; no separate chart module import is required. --- ## The Chart API at a Glance | What you want | How to do it | |---|---| | Add a column chart | `ws.charts.add_bar(top_row, left_col, bottom_row, right_col)` | | Add a line chart | `ws.charts.add_line(top_row, left_col, bottom_row, right_col)` | | Add a bar chart | `ws.charts.add_bar(top_row, left_col, bottom_row, right_col)` | | Add a pie chart | `ws.charts.add_pie(top_row, left_col, bottom_row, right_col)` | | Set the title | `chart.title = "My Chart"` (plain string; not `.title.text`) | | Set x-axis categories | `chart.category_data = "A2:A6"` | | Add a named series | `chart.n_series.add("B2:B6", category_data="A2:A6", name="Revenue")` | | Show legend | `chart.show_legend = True` | | Set legend position | `chart.legend_position = "bottom"` | All row and column indices are **zero-based**. The `add_*` methods return the `Chart` object directly (not an index). --- ## Column Chart: Step by Step Let's build a column chart showing quarterly revenue and expenses. ### Step 1: Create the workbook and write data Create a `Workbook`, select the first worksheet, and write header and data rows to cells: ```python from aspose.cells_foss import Workbook, Cell wb = Workbook() ws = wb.worksheets[0] ws.name = "Q1-Q4 Report" ##Headers ws.cells["A1"].value = "Quarter" ws.cells["B1"].value = "Revenue" ws.cells["C1"].value = "Expenses" ##Data quarters = ["Q1", "Q2", "Q3", "Q4"] revenue = [50000, 62000, 71000, 89000] expenses = [32000, 38000, 41000, 47000] for i, (q, r, e) in enumerate(zip(quarters, revenue, expenses), start=2): ws.cells[f"A{i}"].value = q ws.cells[f"B{i}"].value = r ws.cells[f"C{i}"].value = e ``` ### Step 2: Add the chart Position the chart below the data (row 7 onward, spanning columns 0-8): ```python chart = ws.charts.add_bar(6, 0, 22, 8) ``` ### Step 3: Configure title and legend Set the chart title and legend position using plain string assignment: ```python chart.title = "Quarterly Revenue vs Expenses" chart.show_legend = True chart.legend_position = "bottom" ``` ### Step 4: Add data series Each series needs a value range, category range, and a name: ```python chart.category_data = "A2:A5" chart.n_series.add("B2:B5", category_data="A2:A5", name="Revenue") chart.n_series.add("C2:C5", category_data="A2:A5", name="Expenses") ``` ### Step 5: Save Call `Workbook.save()` with a filename ending in `.xlsx` to write the workbook to disk: ```python wb.save("quarterly_report.xlsx") print("Chart saved to quarterly_report.xlsx") ``` The following block assembles all five steps into a single runnable script: ```python from aspose.cells_foss import Workbook, Cell wb = Workbook() ws = wb.worksheets[0] ws.name = "Q1-Q4 Report" ##Data ws.cells["A1"].value = "Quarter" ws.cells["B1"].value = "Revenue" ws.cells["C1"].value = "Expenses" data = [("Q1", 50000, 32000), ("Q2", 62000, 38000), ("Q3", 71000, 41000), ("Q4", 89000, 47000)] for i, (q, r, e) in enumerate(data, start=2): ws.cells[f"A{i}"].value = q ws.cells[f"B{i}"].value = r ws.cells[f"C{i}"].value = e chart = ws.charts.add_bar(6, 0, 22, 8) chart.title = "Quarterly Revenue vs Expenses" chart.category_data = "A2:A5" chart.n_series.add("B2:B5", category_data="A2:A5", name="Revenue") chart.n_series.add("C2:C5", category_data="A2:A5", name="Expenses") chart.show_legend = True chart.legend_position = "bottom" wb.save("quarterly_report.xlsx") ``` --- ## Line Chart: Monthly Trend The same pattern used for column charts applies to `add_line()` — replace `add_bar()` with `add_line()` to produce a line chart instead: ```python from aspose.cells_foss import Workbook, Cell wb = Workbook() ws = wb.worksheets[0] months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] actuals = [42000, 47500, 53000, 49000, 61000, 68000] targets = [45000, 45000, 50000, 55000, 60000, 65000] ws.cells["A1"].value = "Month" ws.cells["B1"].value = "Actual" ws.cells["C1"].value = "Target" for i, (m, a, t) in enumerate(zip(months, actuals, targets), start=2): ws.cells[f"A{i}"].value = m ws.cells[f"B{i}"].value = a ws.cells[f"C{i}"].value = t chart = ws.charts.add_line(8, 0, 24, 8) chart.title = "Monthly Revenue: Actual vs Target" chart.category_data = "A2:A7" chart.n_series.add("B2:B7", category_data="A2:A7", name="Actual") chart.n_series.add("C2:C7", category_data="A2:A7", name="Target") chart.show_legend = True chart.legend_position = "right" wb.save("monthly_trend.xlsx") ``` --- ## Pie Chart: Market Share The following example creates a pie chart with market share data. Call `add_pie()` and configure category and series ranges the same way as other chart types: ```python from aspose.cells_foss import Workbook, Cell wb = Workbook() ws = wb.worksheets[0] segments = ["Product A", "Product B", "Product C", "Product D"] shares = [40, 25, 20, 15] ws.cells["A1"].value = "Segment" ws.cells["B1"].value = "Share %" for i, (s, v) in enumerate(zip(segments, shares), start=2): ws.cells[f"A{i}"].value = s ws.cells[f"B{i}"].value = v chart = ws.charts.add_pie(6, 0, 20, 7) chart.title = "Market Share by Product" chart.category_data = "A2:A5" chart.n_series.add("B2:B5", category_data="A2:A5", name="Share") chart.show_legend = True chart.legend_position = "right" wb.save("market_share.xlsx") ``` --- ## Common Mistakes to Avoid | Wrong | Right | |---|---| | `ws.charts.add(ChartType.COLUMN, 5, 0, 15, 5)` | `ws.charts.add_bar(5, 0, 15, 5)` | | `chart.title.text = "Revenue"` | `chart.title = "Revenue"` | | `chart.n_series.add("B2:B5", True)` (positional) | `chart.n_series.add("B2:B5", category_data="A2:A5", name="Revenue")` | | `from aspose.cells.charts import ChartType` | Not needed; use `ws.charts.add_bar()` directly | | `chart.n_series.category_data = "A2:A5"` | `chart.category_data = "A2:A5"` (chart level) | --- ## Getting Started You now have working examples for column, line, and pie charts in Aspose.Cells FOSS for Python. The chart API follows a consistent pattern: call the `add_*` method, set the title and legend, add named series with `n_series.add()`, and call `Workbook.save()`. ## Resources - [Aspose.Cells FOSS for Python: Installation](https://docs.aspose.org/cells/python/getting-started/installation/) - [Developer Guide: Working with Charts](https://docs.aspose.org/cells/python/developer-guide/working-with-charts/) - [API Reference: ChartCollection, Chart, NSeries](https://reference.aspose.org/cells/python/) - [Knowledge Base: How to Create Charts in Python](https://kb.aspose.org/cells/python/how-to-create-charts-python/) - [Product Overview](https://products.aspose.org/cells/python/): Features and capabilities summary - [GitHub Repository](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Python) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for Python — Enterprise Product](https://products.aspose.com/cells/python-java/) --- # Create Hyperlinks in Excel Files Using Aspose.Cells FOSS for Python URL: https://blog.aspose.org/cells/python/aspose-cells-foss-python-excel-hyperlinks/ Learn how to add URL, email, file, and internal worksheet hyperlinks to Excel files in Python using the Workbook class in Aspose.Cells FOSS — no Microsoft Office required. --- Product: Aspose.Cells Platform: python Page Type: index Canonical URL: https://blog.aspose.org/cells/python/aspose-cells-foss-python-excel-hyperlinks/ --- # Create Hyperlinks in Excel Files Using Aspose.Cells FOSS for Python ## Introduction The `Workbook` class in Aspose.Cells FOSS enables developers to embed hyperlinks directly into Excel workbooks, supporting multiple link types including URLs, email addresses, external files, and internal worksheet references. This capability streamlines the creation of interactive spreadsheets that connect users to external resources or navigate complex internal structures with a single click. Hyperlinks improve usability by allowing users to jump from data points to supporting documentation, contact information, or related sheets without leaving the spreadsheet environment. The library handles all common hyperlink scenarios natively, ensuring compatibility with Excel's hyperlink behavior and formatting standards. ## Key Highlights - Supports URL hyperlinks (e.g., https://example.com) for web navigation - Enables email hyperlinks (mailto:address) to open the default email client - Allows linking to external files (e.g., file://C:/docs/report.xlsx) via absolute or relative paths - Supports internal references (e.g., 'Sheet2!A1') to jump between worksheets within the same workbook - Automatically applies Excel's default hyperlink style (blue, underlined) to new links - Integrates with the `Workbook`'s protection model to preserve link integrity under sheet/workbook protection ## Getting Started To create a hyperlink in a cell, assign a formula using the `=HYPERLINK()` function. The library recognizes and preserves this formula as a functional hyperlink when the workbook is saved. ```python from aspose.cells_foss import Workbook wb = Workbook() ws = wb.worksheets[0] # URL hyperlink ws.cells["A1"].formula = '=HYPERLINK("https://example.com","Visit Example")' # Email hyperlink ws.cells["A2"].formula = '=HYPERLINK("mailto:user@example.com","Send Email")' # Internal reference (same workbook, different sheet) ws.cells["A3"].formula = '=HYPERLINK("#Sheet2!A1","Go to Sheet2")' wb.save("hyperlinks.xlsx") ``` The `=HYPERLINK()` formula takes two arguments: the link target (URL, `mailto:`, or `#SheetName!Cell`) and the display text. Excel and LibreOffice render this as a clickable blue underlined link. ## See Also - [Introducing Aspose.Cells FOSS for Python](https://blog.aspose.org/cells/python/python-excel-xlsx-library/) - [Work with formulas in spreadsheets](https://docs.aspose.org/cells/python/developer-guide/formula-calculation/) - [Perform spreadsheet operations efficiently](https://docs.aspose.org/cells/python/developer-guide/spreadsheet-operations/) - [Convert between file formats](https://kb.aspose.org/cells/python/how-to-convert-csv-to-json-python/) - [Fix common errors and troubleshooting](https://kb.aspose.org/cells/python/troubleshooting/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for Python — Enterprise Product](https://products.aspose.com/cells/python-java/) --- # Spreadsheet Management in Python with Aspose.Cells FOSS URL: https://blog.aspose.org/cells/python/cells-spreadsheet-management-python/ Manage Excel spreadsheets in Python with aspose-cells-foss. Create workbooks, style cells, build charts, validate data, and export to CSV, JSON, and Markdown — all MIT licensed. --- Product: Aspose.Cells Platform: python Page Type: index Canonical URL: https://blog.aspose.org/cells/python/cells-spreadsheet-management-python/ --- # Spreadsheet Management in Python with Aspose.Cells FOSS ## Introduction Working with Excel spreadsheets programmatically is a common requirement in data processing, reporting, and automation workflows. **aspose-cells-foss** is an open-source Python library that lets you create, read, and modify `.xlsx` workbooks without any dependency on Microsoft Excel or other office suites. Released under the **MIT license**, aspose-cells-foss provides a rich API surface covering cell values, formulas, styling, charts, tables, shapes, pictures, data validation, comments, hyperlinks, auto-filters, and conditional formatting. The library requires Python 3.7 or higher and installs with a single `pip` command. This post walks through the spreadsheet management capabilities that aspose-cells-foss brings to your Python projects, with working code examples grounded in the actual API. --- ## What's Included ### Cell Values and Formulas The `Cell` class supports integers, floats, strings, and formulas. You can set a value directly through `put_value()` or assign a formula string to the `formula` property. The `FormulaEvaluator` class can evaluate formulas programmatically. ```python from aspose.cells_foss import Workbook, Cell wb = Workbook() ws = wb.worksheets[0] # Set different value types ws.cells["A1"] = Cell(42) ws.cells["A2"] = Cell(3.14159) ws.cells["A3"] = Cell("Revenue Report") # Set a formula ws.cells["A4"] = Cell(None, "=SUM(A1:A2)") # Check the stored values print(ws.cells["A1"].value) # 42 print(ws.cells["A4"].formula) # =SUM(A1:A2) ``` ### Styling and Formatting The `Style` class provides methods for fills, borders, number formats, and alignment. Apply a style to any cell with `Cell.apply_style()`. ```python from aspose.cells_foss import Workbook, Cell, Style wb = Workbook() ws = wb.worksheets[0] ws.cells["A1"] = Cell("Total") ws.cells["B1"] = Cell(25000) style = Style() style.set_fill_color("FFD9E1F2") style.set_border("bottom", "thin", "FF000000", 1) style.set_number_format("#,##0.00") ws.cells["B1"].apply_style(style) wb.save("styled_report.xlsx") ``` ### Charts The `ChartCollection` class offers dedicated `add_line()`, `add_bar()`, `add_pie()`, `add_scatter()`, and many other methods to insert charts into a worksheet. Once created, configure the `Chart` object's title, legend, category data, and series. ```python from aspose.cells_foss import Workbook wb = Workbook() ws = wb.worksheets[0] # Populate data months = ["Jan", "Feb", "Mar", "Apr"] sales = [120, 150, 180, 200] for i, (m, s) in enumerate(zip(months, sales), 2): ws.cells[f"A{i}"].value = m ws.cells[f"B{i}"].value = s ws.cells["A1"].value = "Month" ws.cells["B1"].value = "Sales" # Create a line chart chart = ws.charts.add_line(0, 4, 20, 12) chart.title = "Monthly Sales" chart.category_data = "A2:A5" chart.n_series.add("B2:B5", category_data="A2:A5", name="Sales") chart.show_legend = True wb.save("sales_chart.xlsx") ``` ### Data Validation The `DataValidation` class lets you enforce dropdown lists, number ranges, and custom validation rules on cell ranges. Properties include `type`, `operator`, `formula1`, `formula2`, `alert_style`, `error_title`, and `error_message`. ```python from aspose.cells_foss import Workbook wb = Workbook() ws = wb.worksheets[0] # Add a dropdown validation dv = ws.data_validations.add("B2:B100") dv.type = 3 # List validation dv.formula1 = '"Yes,No,Pending"' dv.show_error_message = True dv.error_title = "Invalid Entry" dv.error_message = "Please select Yes, No, or Pending." wb.save("validated.xlsx") ``` ### Auto-Filters and Tables Apply auto-filtering with the `AutoFilter` class by calling `set_range()` and then filtering individual columns. For structured data, the `TableCollection.add()` method creates ListObject tables with styles and auto-filters. ```python from aspose.cells_foss import Workbook wb = Workbook() ws = wb.worksheets[0] # Populate header + data ws.cells["A1"].value = "Name" ws.cells["B1"].value = "Score" for i, (n, s) in enumerate([("Alice", 92), ("Bob", 78), ("Carol", 95)], 2): ws.cells[f"A{i}"].value = n ws.cells[f"B{i}"].value = s # Apply an auto-filter ws.auto_filter.set_range(0, 0, 3, 1) # Or create a structured table table = ws.tables.add(0, 0, 3, 1, True, "ScoreTable") wb.save("filtered_data.xlsx") ``` ### Workbook and Worksheet Protection Protect workbooks with `Workbook.protect()` and individual worksheets with `Worksheet.protect()`. The protection API supports granular permissions such as allowing formatting or inserting rows while blocking deletions. ```python from aspose.cells_foss import Workbook wb = Workbook() ws = wb.worksheets[0] ws.cells["A1"].value = "Protected content" # Protect the worksheet with a password ws.protect("secret123", format_cells=True, insert_rows=True, delete_columns=False, delete_rows=False) # Protect the workbook structure wb.protect("workbook_pass", lock_structure=True, lock_windows=False) wb.save("protected.xlsx") ``` --- ## Quick Start Install the package from PyPI: Create a workbook, populate some data, and save it: ```python from aspose.cells_foss import Workbook, Cell, Style # Create a new workbook wb = Workbook() ws = wb.worksheets[0] ws.name = "Quarterly Report" # Add headers with styling header_style = Style() header_style.set_fill_color("FF4472C4") for col, label in enumerate(["Region", "Q1", "Q2", "Q3", "Q4"], 1): cell_ref = f"{chr(64 + col)}1" ws.cells[cell_ref] = Cell(label) ws.cells[cell_ref].apply_style(header_style) # Add data rows data = [ ("North", 12000, 15000, 13000, 16000), ("South", 9000, 11000, 10500, 12000), ("East", 14000, 13500, 15000, 17000), ] for r, row in enumerate(data, 2): for c, val in enumerate(row, 1): ws.cells[f"{chr(64 + c)}{r}"].value = val # Save as XLSX wb.save("quarterly_report.xlsx") # Also export to CSV wb.save_as_csv("quarterly_report.csv") ``` --- ## Supported Formats | Format | Extension | Read | Write | |----------|-------------|------|-------| | XLSX | `.xlsx` | Yes | Yes | | CSV | `.csv` | Yes | Yes | | TSV | `.tsv` | No | Yes | | JSON | `.json` | No | Yes | | Markdown | `.md` | No | Yes | The `SaveFormat` enum defines these output formats: `AUTO`, `XLSX`, `CSV`, `TSV`, `MARKDOWN`, and `JSON`. The library reads `.xlsx` files natively and can import CSV data through `Workbook.load_csv()`. --- ## Open Source & Licensing aspose-cells-foss is released under the **MIT license**, which permits unrestricted use in both commercial and non-commercial projects. The source code is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Python.git). The library depends on `pycryptodome` (>= 3.15.0) and `olefile` (>= 0.46) for encryption support. --- ## Getting Started Explore the full documentation and reference material to start building with aspose-cells-foss: - **Developer Guide**: [docs.aspose.org/cells/python/](https://docs.aspose.org/cells/python/) - **Knowledge Base**: [kb.aspose.org/cells/python/](https://kb.aspose.org/cells/python/) - **API Reference**: [reference.aspose.org/cells/python/](https://reference.aspose.org/cells/python/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Cells FOSS for Python URL: https://blog.aspose.org/cells/python/python-excel-xlsx-library/ Aspose.Cells FOSS is a lightweight Python library with minimal dependencies for creating, reading, and modifying Excel files without Microsoft Excel. MIT licensed. --- Product: Aspose.Cells Platform: python Page Type: index Canonical URL: https://blog.aspose.org/cells/python/python-excel-xlsx-library/ --- # Introducing Aspose.Cells FOSS for Python ## Introduction Aspose.Cells FOSS is a lightweight Python library for creating, reading, and modifying Excel files (`.xlsx` format) without requiring Microsoft Excel. It is released under the MIT License and available on PyPI as `aspose-cells-foss`. Install it with: ## What It Can Do The library covers the full range of spreadsheet operations: - **Create and edit workbooks**: create new workbooks or modify existing `.xlsx` files using the `Workbook` and `Worksheet` classes - **Cell operations**: read and write cell values, formulas, and styles - **Styling**: apply fonts, colors, borders, number formats, and alignment - **Multiple worksheets**: add, remove, and manage worksheets - **Data validation**: define dropdown lists, number ranges, and custom validation rules - **Comments**: add cell comments with author metadata - **Hyperlinks**: link to URLs, emails, files, and internal references - **Auto-filters**: filter data ranges with `AutoFilter` - **Conditional formatting**: apply rules-based formatting to highlight cell values - **Charts**: create charts; 16 `ChartType` values are defined, but only **5 serialize to XLSX without error**: Line, Bar, Pie, Area, and Stock. The remaining 11 types (Scatter, Waterfall, Combo, Surface, Radar, Treemap, Sunburst, Histogram, Funnel, Box & Whisker, Map) raise `NotImplementedError` on save. - **Pictures**: embed images (JPEG, PNG) anchored to cells - **Drawing shapes**: add rectangles, ovals, arrows, text boxes, and 30+ preset shapes - **Sparklines**: embed mini Line, Column, and Win-Loss charts inside cells - **Excel tables**: create structured tables (`Table`, accessed via `ws.tables`) with auto-filter and column headers - **Page breaks**: add horizontal and vertical page breaks - **Merge cells**: merge and unmerge cell ranges - **Password protection**: protect files with AES encryption - **Export formats**: save as XLSX, CSV, Markdown, or JSON ## Getting Started Install the library with a single command: Then verify the installation: ```python from aspose.cells_foss import Workbook print('Aspose.Cells FOSS for Python is ready.') ``` ## Quick Start ```python from aspose.cells_foss import Workbook # Create a new workbook workbook = Workbook() worksheet = workbook.worksheets[0] # Write values worksheet.cells["A1"].put_value("Hello") worksheet.cells["B1"].put_value("World") worksheet.cells["A2"].put_value(42) # Save workbook.save("output.xlsx") ``` Reading an existing file: ```python from aspose.cells_foss import Workbook workbook = Workbook("input.xlsx") worksheet = workbook.worksheets[0] value = worksheet.cells["A1"].value print(f"A1: {value}") ``` ## See Also - [Creating Charts in Python](/cells/python/aspose-cells-foss-python-excel-chart-tutorial/) - [Work with formulas](https://docs.aspose.org/cells/python/developer-guide/formula-calculation/) - [Load spreadsheets](https://kb.aspose.org/cells/python/how-to-load-spreadsheets-python/) - [Save spreadsheets](https://kb.aspose.org/cells/python/how-to-save-spreadsheets-python/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for Python — Enterprise Product](https://products.aspose.com/cells/python-java/) --- # Core Workbook and Cell APIs in Aspose.Cells FOSS for Rust URL: https://blog.aspose.org/cells/rust/cells-core-api-rust/ A systematic tour of the core API surface of Aspose.Cells FOSS for Rust: Workbook and Worksheet fundamentals, typed cell values and formulas, document properties, worksheet protection and visibility, row/column sizing with merged cells, and defensive loading with diagnostics. --- Product: Aspose.Cells Platform: rust Page Type: index Canonical URL: https://blog.aspose.org/cells/rust/cells-core-api-rust/ --- # Core Workbook and Cell APIs in Aspose.Cells FOSS for Rust ## Introduction Aspose.Cells FOSS for Rust exposes its functionality through the `aspose-cells-foss-rust` crate, centered on a compact set of core types: `Workbook`, `Worksheet`, `Cells`, `Cell`, and `DocumentProperties`, each with matching `*Mut` accessors for write access. This post is a systematic tour of that core API surface — not one narrow feature, but the fundamentals every application built on the crate ends up using: creating and naming worksheets, reading and writing typed cell values, setting document metadata, protecting and hiding worksheets, sizing rows and columns, merging cells, and loading files defensively. The crate is MIT licensed and targets Rust edition 2021. Nearly every fallible operation returns `Result`, so error handling with the `?` operator runs through the examples below the same way it runs through real code. The crate does pull in a small set of runtime dependencies rather than reimplementing everything from scratch — `chrono` for date-time values, `zip` for the XLSX package format, `roxmltree` for XML parsing, `serde_json` for structured data, `sha2` and `base64` for hashing and encoding, and `getrandom` for randomness. Each section below covers one area of the API with the concrete types and methods involved, backed by working Rust examples drawn from the crate's own sample code. --- ## Key Features ### Workbook and Worksheet Fundamentals A `Workbook` starts empty with `Workbook::new()`, carrying one worksheet named `"Sheet1"`. Additional sheets come from `WorksheetsMut::add(name)`, which returns the new sheet's index. `Worksheets`/`WorksheetsMut` also track which sheet is active via `active_sheet_name()` and `set_active_sheet_name()`. ```rust let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; sheet.set_name("Summary")?; let detail_index = worksheets.add("Detail")?; let detail = worksheets.get(detail_index)?; detail.get_cells_mut().get("A1")?.put_value_string("Detail data")?; worksheets.set_active_sheet_name("Detail")?; } let sheets = workbook.get_worksheets(); println!("Worksheet count: {}", sheets.count()); println!("Active sheet: {}", sheets.active_sheet_name()); ``` ### Typed Cell Values and Formulas `Cells`/`CellsMut` address a cell by A1-style reference (`get("B3")`) or by row/column index (`get_by_index(row, column)`). Each `Cell`/`CellMut` accepts typed values through dedicated setters, so no stringly-typed conversions are required, and formulas are written together with a cached value so the file opens with correct results before any recalculation. ```rust let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Hello")?; cells.get("B1")?.put_value_i32(123)?; cells.get("C1")?.put_value_bool(true)?; cells.get("D1")?.put_value_decimal(12.5)?; cells.get("F1")?.put_value_i32(10)?; cells.get("G1")? .put_formula_with_cached_value("=F1*2", CellValue::Number(20.0))?; } workbook.save("typed-values.xlsx")?; let loaded = Workbook::load_xlsx("typed-values.xlsx")?; let sheet = loaded.worksheet("Sheet1")?; let cells = sheet.get_cells(); println!( "{:?}: {}", cells.get("B1")?.value_type(), cells.get("B1")?.display_string_value() ); println!("G1 cached value -> {}", cells.get("G1")?.display_string_value()); ``` ### Document Properties `Workbook::get_document_properties_mut()` reaches a `DocumentProperties` object covering the common metadata fields (title, subject, author, keywords, category, company), plus a nested `CoreDocumentProperties` (`get_core_mut()`) and `ExtendedDocumentProperties` (`get_extended_mut()`) for OOXML core/extended property sets. ```rust { let properties = workbook.get_document_properties_mut(); properties.set_title("Annual Sales Report 2024"); properties.set_subject("Financial Performance Analysis"); properties.set_author("Finance Department"); properties.set_keywords("sales, finance, 2024, report"); properties.set_category("Financial Reports"); properties.set_company("Acme Corporation"); let core = properties.get_core_mut(); core.set_creator("Finance Department"); core.set_created(Some(Utc::now())); let extended = properties.get_extended_mut(); extended.set_company("Acme Corporation"); } workbook.save("with-properties.xlsx")?; let loaded = Workbook::load_xlsx("with-properties.xlsx")?; let properties = loaded.get_document_properties(); println!("Title: {}", properties.get_title()); println!("Core creator: {}", properties.get_core().get_creator()); ``` ### Worksheet Protection and Visibility A `Worksheet` can be hidden with `set_visibility_type(VisibilityType::Hidden)`, tinted with `set_tab_color`, and locked down with `protect()` plus a `WorksheetProtection` object (via `get_protection_mut()`) that controls exactly which actions — formatting cells, selecting locked cells, and so on — stay available once protection is on. ```rust let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let layout = worksheets.get(0)?; layout.set_name("Layout")?; layout.set_visibility_type(VisibilityType::Hidden); layout.set_tab_color(Color::from_argb(255, 34, 68, 102)); layout.set_show_gridlines(false); layout.set_right_to_left(true); layout.set_zoom(85)?; layout.protect(); let protection = layout.get_protection_mut(); protection.set_objects(true); protection.set_format_cells(true); protection.set_select_locked_cells(true); } workbook.save("protected.xlsx")?; let loaded = Workbook::load_xlsx("protected.xlsx")?; let sheet = loaded.worksheet("Layout")?; println!("Visibility: {:?}", sheet.get_visibility_type()); println!("Protected: {}", sheet.is_protected()); ``` ### Rows, Columns, and Merged Cells `CellsMut` exposes `get_rows()`/`get_columns()` as `RowsMut`/`ColumnsMut` for sizing and hiding individual rows and columns, and `merge(first_row, first_column, total_rows, total_columns)` to combine a range of cells into one merged region. ```rust let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Merged")?; cells.get("C4")?.put_value_i32(99)?; cells.get_rows().get(1).set_height(22.5)?; cells.get_rows().get(3).set_is_hidden(true)?; cells.get_columns().get(0).set_width(18.25)?; cells.get_columns().get(2).set_is_hidden(true)?; let mut cells = sheet.get_cells_mut(); cells.merge(0, 0, 2, 2)?; } workbook.save("rows-columns.xlsx")?; let loaded = Workbook::load_xlsx("rows-columns.xlsx")?; let sheet = loaded.worksheet("Sheet1")?; println!( "Row 2 height: {}", sheet.get_rows().get(1).get_height().unwrap_or_default() ); println!( "Column A width: {}", sheet.get_columns().get(0).get_width().unwrap_or_default() ); println!("Merged regions: {}", sheet.get_cells().get_merged_cells().len()); ``` ### Defensive Loading with Diagnostics Real-world XLSX files are not always well-formed. `LoadOptions` exposes repair flags (`try_repair_package`, `try_repair_xml`), and `Workbook::get_load_diagnostics()` returns a `LoadDiagnostics` object whose `issues()` reports what the loader found and repaired. ```rust let options = LoadOptions { try_repair_package: true, try_repair_xml: true, ..LoadOptions::default() }; let loaded = Workbook::load_xlsx_with_options(&path, &options)?; let sheet = loaded.worksheet("Sheet1")?; let cells = sheet.get_cells(); println!( "Loaded workbook with {} worksheet(s) and {} diagnostic issue(s).", loaded.get_worksheets().count(), loaded.get_load_diagnostics().issues().len() ); println!("First item: {}", cells.get("A2")?.display_string_value()); ``` --- ## Quick Start A minimal session touching workbook, worksheet, cell, and document-property basics: ```rust use aspose_cells_foss_rust::{CellValue, Workbook}; use std::error::Error; fn main() -> Result> { let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; sheet.set_name("Report")?; let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Item")?; cells.get("B1")?.put_value_string("Quantity")?; cells.get("A2")?.put_value_string("Widgets")?; cells.get("B2")?.put_value_i32(12)?; cells.get("B3")? .put_formula_with_cached_value("=SUM(B2:B2)", CellValue::Number(12.0))?; } workbook.get_document_properties_mut().set_title("Quick Start Report"); workbook.save("report.xlsx")?; let loaded = Workbook::load_xlsx("report.xlsx")?; let sheet = loaded.worksheet("Report")?; let cells = sheet.get_cells(); println!("Title: {}", loaded.get_document_properties().get_title()); println!("Total formula -> {}", cells.get("B3")?.display_string_value()); Ok(()) } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | XLSX | `.xlsx` | ✓ | ✓ | XLSX is the focus of the current release: full round-trip read and write via `Workbook::load_xlsx` and `Workbook::save`, with `LoadFormat` and `SaveFormat` enums governing explicit format selection. --- ## Open Source & Licensing Aspose.Cells FOSS for Rust is MIT licensed. The complete source code is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Rust), and the license permits commercial use, modification, and redistribution. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/rust/getting-started/) - [Installation](https://docs.aspose.org/cells/rust/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/cells/rust/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/rust/) - [API Reference](https://reference.aspose.org/cells/rust/) - [Product Page](https://products.aspose.org/cells/rust/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for Rust — Enterprise Product](https://products.aspose.com/cells/rust/) --- # Spreadsheet Management in Rust with Aspose.Cells FOSS URL: https://blog.aspose.org/cells/rust/cells-spreadsheet-management-rust/ A tour of spreadsheet management in Aspose.Cells FOSS for Rust: worksheets and cell collections, typed values and formulas, styling with CellStyle and StyleFlag, page setup, comments, hyperlinks, and structured tables — all writing real XLSX files without Microsoft Office. --- Product: Aspose.Cells Platform: rust Page Type: index Canonical URL: https://blog.aspose.org/cells/rust/cells-spreadsheet-management-rust/ --- # Spreadsheet Management in Rust with Aspose.Cells FOSS ## Introduction Spreadsheet management is the core of the `aspose-cells-foss-rust` crate: the objects that model a workbook, its sheets, and their cells, and the operations that turn Rust data into presentable XLSX files. This post walks through that surface — from creating sheets and writing typed values to styling, page layout, and the structural features that make workbooks usable: comments, hyperlinks, tables, and defined names. Everything shown here is part of the open-source, MIT-licensed crate. No Microsoft Office installation is involved at any point; the library reads and writes the XLSX package format directly. This section has been reviewed against the current source model for the latest product behavior and API coverage. --- ## Key Features ### Worksheets and Cell Collections Worksheets are managed through the workbook's worksheet collections. Sheets are addressed by index or name, renamed with `set_name`, and their cells are reached through `get_cells` (read) or `get_cells_mut` (write): ```rust let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; sheet.set_name("Charts")?; { let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Month")?; cells.get("B1")?.put_value_string("Sales")?; } } ``` ### Typed Values by Name or Index Cells accept strings, integers, booleans, decimals, and date-times through typed setters. Cells can be addressed A1-style (`get("B3")`) or numerically (`get_by_index(row, column)`), which suits generated layouts: ```rust for month in 1..=12_u32 { cells .get_by_index(month, 0) .put_value_string(format!("Month {month}"))?; cells .get_by_index(month, 1) .put_value_i32((month as i32 * 1000) + (month as i32 * 50))?; } ``` ### Formulas with Cached Values `put_formula_with_cached_value` stores the formula text together with the value Excel should display before its first recalculation — important when the file is consumed by other tools that read cached results: ```rust cells.get("F1")?.put_value_i32(10)?; cells.get("G1")? .put_formula_with_cached_value("=F1*2", CellValue::Number(20.0))?; ``` ### Styling and Page Layout `CellStyle` carries `Font`, `Fill`, and `Borders`; `StyleFlag` selects which style aspects an update applies. `NumberFormat` controls value rendering, and `PageSetup` manages `PaperSizeType` and `PageOrientationType` for printing. `FreezePane` and row/column `VisibilityType` keep large sheets navigable. ### Comments, Hyperlinks, and Names Reviewer workflows and navigation are covered by `Comment` and `CommentCollection`, `Hyperlink` with `HyperlinkCollection`, and `DefinedName` with `DefinedNameCollection` for named ranges. ### Structured Tables and Filters `ListObject` turns a range into a structured table with `TableStyleType` styling and `TotalsCalculation` rows; `AutoFilter` adds filtering with `FilterColumn` and `FilterOperatorType` conditions. --- ## Quick Start Add the crate to your `Cargo.toml` as a git dependency (the crate is not yet published on crates.io): A minimal spreadsheet-management session — create, write, save, reload: ```rust use aspose_cells_foss_rust::{CellValue, Workbook}; use std::error::Error; fn main() -> Result> { let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Item")?; cells.get("B1")?.put_value_string("Quantity")?; cells.get("A2")?.put_value_string("Apples")?; cells.get("B2")?.put_value_i32(12)?; } workbook.save("inventory.xlsx")?; let loaded = Workbook::load_xlsx("inventory.xlsx")?; let sheet = loaded.worksheet("Sheet1")?; let cells = sheet.get_cells(); println!("A2 = {}", cells.get("A2")?.display_string_value()); Ok(()) } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | XLSX | `.xlsx` | ✓ | ✓ | Loading accepts `LoadOptions` repair flags (`try_repair_package`, `try_repair_xml`) with structured `LoadDiagnostics`; saving goes through `save`, `save_xlsx`, or `save_with_format` with the `SaveFormat` enum. --- ## Open Source & Licensing Aspose.Cells FOSS for Rust is MIT licensed. Source code lives on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Rust); commercial use, modification, and redistribution are permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/rust/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/rust/developer-guide/) - [Working with Spreadsheet Management](https://docs.aspose.org/cells/rust/developer-guide/working-with-spreadsheet-management/) - [KB Articles](https://kb.aspose.org/cells/rust/) - [API Reference](https://reference.aspose.org/cells/rust/) - [Product Page](https://products.aspose.org/cells/rust/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Cells FOSS for Rust — Open-Source Excel XLSX Library URL: https://blog.aspose.org/cells/rust/introducing-cells-foss-rust/ Aspose.Cells FOSS for Rust is an open-source, MIT-licensed crate for creating, loading, editing, and saving Excel XLSX workbooks in Rust — typed cell values, formulas with cached results, charts, styles, validation, and auto-filters, with no Microsoft Office dependency. --- Product: Aspose.Cells Platform: rust Page Type: index Canonical URL: https://blog.aspose.org/cells/rust/introducing-cells-foss-rust/ --- # Introducing Aspose.Cells FOSS for Rust — Open-Source Excel XLSX Library ## Introduction Aspose.Cells FOSS for Rust brings the Aspose.Cells FOSS family to the Rust ecosystem. The `aspose-cells-foss-rust` crate lets Rust applications create Excel XLSX workbooks from scratch, load existing files, modify their contents, and save the result — with no Microsoft Office installation, COM automation, or external runtime involved. The crate is MIT licensed and targets Rust edition 2021. It follows the conventions Rust developers expect: constructors like `Workbook::new`, `Result`-based error handling through `CellsError`, and explicit mutable accessors such as `get_worksheets_mut` and `get_cells_mut` that keep borrow rules clear. If you build backend services, CLI tools, or data pipelines that need to produce or consume spreadsheets, this library gives you a native way to do it. This section has been reviewed against the current source model for the latest product behavior and API coverage. Aspose.Cells FOSS is already available for .NET, C++, Java, Python, and TypeScript; the Rust crate joins the family with the same focus: honest, verifiable XLSX support under a permissive license. --- ## What's Included ### Workbooks, Worksheets, and Typed Cell Values A `Workbook` starts with one worksheet and grows via `add_worksheet`. Cells accept typed values — strings, integers, booleans, decimals, and date-times — through dedicated setters, so no stringly-typed conversions are needed: ```rust let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Hello")?; cells.get("B1")?.put_value_i32(123)?; cells.get("C1")?.put_value_bool(true)?; cells.get("D1")?.put_value_decimal(12.5)?; } workbook.save("hello.xlsx")?; ``` ### Formulas with Cached Results Formulas are written together with a cached value, so the saved file opens in Excel with correct results immediately — no recalculation pass required: ```rust cells.get("F1")?.put_value_i32(10)?; cells.get("G1")? .put_formula_with_cached_value("=F1*2", CellValue::Number(20.0))?; ``` ### Charts Anchored to Data Ranges Column, line, and other chart types from the `ChartType` enum can be anchored to cell ranges on a worksheet, and chart geometry can be read back from loaded files: ```rust let mut charts = sheet.get_charts(); charts.add( ChartType::Column, "Charts!$B$1:$B$13".to_string(), 0, 4, 18, 8, )?; ``` ### Styling, Page Setup, and Structure Cell formatting flows through `CellStyle` with `Font`, `Fill`, and `Borders`, applied selectively with `StyleFlag`. `PageSetup` controls paper size and orientation for print, `FreezePane` keeps header rows visible, and structured tables come via `ListObject` with `TableStyleType`. ### Validation, Conditional Formatting, and Filters Data-quality features are part of the core surface: `Validation` rules with `OperatorType`, conditional formatting through `FormatCondition`, auto-filters via `AutoFilter`, defined names via `DefinedName`, and workbook or worksheet protection through `WorkbookProtection` and `WorksheetProtection`. ### Defensive Loading with Diagnostics Real-world XLSX files are not always well-formed. `LoadOptions` exposes repair flags, and `LoadDiagnostics` reports what the loader encountered: ```rust let options = LoadOptions { try_repair_package: true, try_repair_xml: true, ..LoadOptions::default() }; let loaded = Workbook::load_xlsx_with_options(&valid_path, &options)?; println!( "Loaded workbook with {} worksheet(s) and {} diagnostic issue(s).", loaded.get_worksheets().count(), loaded.get_load_diagnostics().issues().len() ); ``` --- ## Quick Start Add the crate to your `Cargo.toml` as a git dependency (the crate is not yet published on crates.io): Then create, save, and reload your first workbook: ```rust use aspose_cells_foss_rust::{CellValue, Workbook}; use std::error::Error; fn main() -> Result> { // Create a new workbook (starts with one sheet, "Sheet1"). let mut workbook = Workbook::new(); { let mut worksheets = workbook.get_worksheets_mut(); let sheet = worksheets.get(0)?; let mut cells = sheet.get_cells_mut(); cells.get("A1")?.put_value_string("Hello")?; cells.get("B1")?.put_value_i32(123)?; cells.get("G1")? .put_formula_with_cached_value("=F1*2", CellValue::Number(20.0))?; } workbook.save("hello.xlsx")?; // Load it back. let loaded = Workbook::load_xlsx("hello.xlsx")?; let sheet = loaded.worksheet("Sheet1")?; let cells = sheet.get_cells(); println!("A1 = {}", cells.get("A1")?.display_string_value()); Ok(()) } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | XLSX | `.xlsx` | ✓ | ✓ | XLSX is the focus of the current release: full round-trip read and write via `Workbook::load_xlsx` and `Workbook::save`, with `LoadFormat` and `SaveFormat` enums governing explicit format selection. --- ## Open Source & Licensing Aspose.Cells FOSS for Rust is MIT licensed. The complete source code is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-Rust), and the license permits commercial use, modification, and redistribution. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/rust/getting-started/) - [Installation](https://docs.aspose.org/cells/rust/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/cells/rust/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/rust/) - [API Reference](https://reference.aspose.org/cells/rust/) - [Product Page](https://products.aspose.org/cells/rust/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Cells FOSS for TypeScript URL: https://blog.aspose.org/cells/typescript/ --- Product: Aspose.Cells Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/cells/typescript/ --- # Aspose.Cells FOSS for TypeScript ## Related Resources - [Aspose.Cells for TypeScript — Enterprise Product](https://products.aspose.com/cells/typescript/) ## Related Topics - [Core Workbook and Cell APIs in Aspose.Cells FOSS for TypeScript](https://blog.aspose.org/cells/typescript/cells-core-api-typescript/) - [Spreadsheet Management with Aspose.Cells FOSS for TypeScript](https://blog.aspose.org/cells/typescript/cells-spreadsheet-management-typescript/) - [Introducing Aspose.Cells FOSS for TypeScript](https://blog.aspose.org/cells/typescript/typescript-excel-xlsx-library/) --- # Core Workbook and Cell APIs in Aspose.Cells FOSS for TypeScript URL: https://blog.aspose.org/cells/typescript/cells-core-api-typescript/ A tour of the core API surface of Aspose.Cells FOSS for TypeScript: Workbook and WorksheetCollection management, Cell value and formula access, Style/Font/Border/Alignment formatting, the AutoFilter class, and multi-format export with SaveFormat. --- Product: Aspose.Cells Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/cells/typescript/cells-core-api-typescript/ --- # Core Workbook and Cell APIs in Aspose.Cells FOSS for TypeScript ## Introduction Aspose.Cells FOSS for TypeScript exposes its functionality through a compact set of core classes: `Workbook`, `WorksheetCollection`, `Worksheet`, `Cell`, and `Style`, plus supporting types for formatting and filtering. This post is a systematic tour of that core API surface -- not a single narrow topic, but the fundamentals every application built on the library ends up using: opening and saving workbooks, navigating worksheets, reading and writing cell values and formulas, applying styles, filtering data, and exporting to other formats. Each section below covers one area of the API with the concrete methods and properties involved, backed by working TypeScript examples. The goal is to give you a working mental model of how the pieces fit together, from `new Workbook()` down to individual `Cell` properties. --- ## Key Features ### Workbook and Worksheet Fundamentals A `Workbook` is either created empty with `new Workbook()` or loaded asynchronously from an existing file with `Workbook.load(filePath, password)`. Every workbook exposes `worksheets`, a `WorksheetCollection` that supports indexing, iteration, and array-style methods (`map`, `filter`, `forEach`, `find`, `indexOf`) in addition to `addWorksheet(name)`, `removeWorksheet(index)`, and `moveWorksheet(fromIndex, toIndex)`. Call `workbook.save(filePath, options)` to persist changes. ```typescript const workbook = new Workbook(); const ws1 = workbook.worksheets.addWorksheet(); const ws2 = workbook.worksheets.addWorksheet("CustomSheet1"); console.log("Total worksheets:", workbook.worksheets.length); workbook.worksheets.removeWorksheet(1); console.log("After delete:", workbook.worksheets.length); console.log( "Names:", workbook.worksheets.worksheets.map((w) => w.name), ); await workbook.save("workbook.xlsx"); ``` ### Cell Access and Values A `Worksheet` reads and writes cells through `putValue(key, value)`, `getCell2(key)` (returns a `Cell`, creating it if absent), `getCell(row, col)` (returns `Cell | undefined`), and `getCellByRef(ref)`. Each `Cell` exposes `value`, `formula`, `row`, `col`, and `ref` as properties, and `setFormula()` / `setStyle()` / `setHyperlink()` as methods. ```typescript const workbook = new Workbook(); const sheet = workbook.worksheets[0]!; sheet.putValue("A1", 42); sheet.putValue("A2", "Hello World"); const formulaCell = sheet.getCell2("A3"); formulaCell.setFormula("=A1+10"); console.log("A1 value:", sheet.getCell(0, 0)?.value); console.log("A3 formula:", sheet.getCell(2, 0)?.formula); const byRef = sheet.getCellByRef("A1"); console.log("Ref:", byRef?.ref, "Row:", byRef?.row, "Col:", byRef?.col); await workbook.save("cells.xlsx"); ``` ### Style, Font, Border, and Alignment `Style` groups font, fill, border, alignment, and number-format settings for a cell. Read or replace whole sub-objects with `getFont()`/`setFont()`, `getBorder()`/`setBorder()`, and `getAlignment()`/`setAlignment()`, or use the convenience setters directly on `Style`, such as `setFontName()`, `setFontSize()`, `setBold()`, `setHorizontalAlignment()`, and `setNumberFormat()`. Apply the finished `Style` to a cell with `Cell.setStyle()`. ```typescript const workbook = new Workbook(); const sheet = workbook.worksheets[0]!; const style = new Style(); style.setFontName("Arial"); style.setFontSize(14); style.setBold(true); style.setNumberFormat("0.00"); style.getBorder().bottom = { style: "thin", color: "000000" }; style.setHorizontalAlignment("center"); style.setVerticalAlignment("center"); style.setWrapText(true); const cell = sheet.getCell2("B2"); cell.putValue(1234.5); cell.setStyle(style); console.log("Bold:", style.isBold(), "Format:", style.getNumberFormat()); await workbook.save("styled.xlsx"); ``` ### Auto-Filtering with the AutoFilter Class `Worksheet.setAutoFilter(range)` is a shortcut for the common case, but the underlying `AutoFilter` class can also be used directly: construct it with a range, then call `addFilterColumn(col, filters, blank)` per column to define which values should remain visible, or `removeFilterColumn(col)` / `clear()` to undo filtering. ```typescript const workbook = new Workbook(); const sheet = workbook.worksheets[0]!; sheet.putValue("A1", "Name"); sheet.putValue("B1", "City"); sheet.putValue("A2", "Alice"); sheet.putValue("B2", "New York"); sheet.putValue("A3", "Bob"); sheet.putValue("B3", "London"); const filter = new AutoFilter("A1:B3"); filter.addFilterColumn(1, ["New York"], false); console.log("Filter range:", filter.range); console.log("Filter columns:", filter.columns.length); await workbook.save("filtered.xlsx"); ``` ### Exporting to HTML, CSV, JSON, and Markdown Beyond `.xlsx`, a `Workbook` can render itself directly as text with `toHtml()`, `toCsv()`, `toJson()`, and `toMarkdown()`, or be saved to a file whose extension selects the format via the `SaveFormat` enum (`XLSX`, `CSV`, `JSON`, `MARKDOWN`, `HTML`). ```typescript const workbook = new Workbook(); const sheet = workbook.worksheets[0]!; sheet.putValue("A1", "Name"); sheet.putValue("B1", "Age"); sheet.putValue("A2", "Alice"); sheet.putValue("B2", 25); sheet.putValue("A3", "Bob"); sheet.putValue("B3", 30); console.log("JSON:", workbook.toJson()); console.log("Markdown:\n", workbook.toMarkdown()); await workbook.save("report.csv"); await workbook.save("report.html"); ``` --- ## Quick Start ```typescript import { Workbook, Style } from "excel-cells"; const workbook = new Workbook(); const sheet = workbook.worksheets.get(0)!; sheet.name = "Summary"; sheet.putValue("A1", "Item"); sheet.putValue("B1", "Count"); sheet.putValue("A2", "Widgets"); sheet.putValue("B2", 12); sheet.putValue("A3", "Gadgets"); sheet.putValue("B3", 7); const totalCell = sheet.getCell2("B4"); totalCell.setFormula("=SUM(B2:B3)"); const numberStyle = new Style(); numberStyle.setNumberFormat("0"); sheet.getCell2("B2").setStyle(numberStyle); sheet.getCell2("B3").setStyle(numberStyle); sheet.getCell2("B4").setStyle(numberStyle); const detail = workbook.worksheets.addWorksheet("Detail"); detail.putValue("A1", "Raw Data"); await workbook.save("summary.xlsx"); const reloaded = await Workbook.load("summary.xlsx"); console.log("Worksheets:", reloaded.worksheets.length); console.log("B4 formula:", reloaded.worksheets.get(0)!.getCell(3, 1)?.formula); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | XLSX | .xlsx | ✓ | ✓ | | HTML | .html | ✓ | ✓ | | CSV | .csv | — | ✓ | | JSON | .json | — | ✓ | | Markdown | .md | — | ✓ | --- ## Open Source & Licensing Aspose.Cells FOSS for TypeScript is released under the MIT license. The source code is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-TypeScript). Commercial use is permitted under the MIT license terms. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/typescript/) - [API Reference](https://reference.aspose.org/cells/typescript/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for TypeScript — Enterprise Product](https://products.aspose.com/cells/typescript/) --- # Spreadsheet Management with Aspose.Cells FOSS for TypeScript URL: https://blog.aspose.org/cells/typescript/cells-spreadsheet-management-typescript/ Explore the spreadsheet management features of Aspose.Cells FOSS for TypeScript including cell styling, data validation, auto-filters, conditional formatting, charts, shapes, and workbook protection. --- Product: Aspose.Cells Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/cells/typescript/cells-spreadsheet-management-typescript/ --- # Spreadsheet Management with Aspose.Cells FOSS for TypeScript ## Introduction Aspose.Cells FOSS for TypeScript provides a comprehensive set of spreadsheet management features beyond basic cell read/write. Developers can apply detailed styling, set up data validation rules, configure auto-filters, add conditional formatting, build charts, insert shapes, and protect workbooks -- all from TypeScript code with no Microsoft Office dependency. This post walks through the key spreadsheet management capabilities available in the library, with working code examples for each feature area. --- ## Key Features ### Data Validation Add validation rules to cell ranges using the `DataValidation` class. Supported validation types include list, number range, and custom formulas. Apply validation to any range with `worksheet.addDataValidation()`. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; const validation = new DataValidation(); validation.type = "list"; validation.formula1 = '"Option1,Option2,Option3"'; worksheet.addDataValidation(validation, "B1:B10"); await workbook.save("validated.xlsx"); ``` ### Auto-Filter Enable auto-filter headers on a data range with `worksheet.setAutoFilter()`. This adds drop-down filter controls to column headers in the output XLSX file. Remove filters with `worksheet.removeAutoFilter()`. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Name"); worksheet.putValue("B1", "Age"); worksheet.putValue("C1", "City"); worksheet.putValue("A2", "Alice"); worksheet.putValue("B2", "25"); worksheet.putValue("C2", "New York"); worksheet.putValue("A3", "Bob"); worksheet.putValue("B3", "30"); worksheet.putValue("C3", "London"); worksheet.setAutoFilter("A1:C4"); await workbook.save("filtered.xlsx"); ``` ### Conditional Formatting Apply visual rules to cell ranges using `ConditionalFormatCollection`. The library supports `ColorScaleRule`, `DataBarRule`, and `IconSetRule` for highlighting cells based on their values. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; for (let i = 1; i <= 10; i++) { worksheet.putValue(`A${i}`, i * 10); } await workbook.save("conditional.xlsx"); ``` ### Hyperlinks and Comments Attach hyperlinks to cells with `cell.setHyperlink()` supporting URLs, email addresses, and internal sheet references. Add comments with `worksheet.addComment()` using `Comment` objects. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Click here"); worksheet.getCell2("A1").setHyperlink("https://www.example.com"); worksheet.putValue("A3", "Send email"); worksheet.getCell2("A3").setHyperlink("mailto:test@example.com"); await workbook.save("hyperlinks.xlsx"); ``` ### Workbook and Cell Protection Protect entire workbooks with a password using `workbook.protect()`. Lock individual cells with `style.setLocked(true)` and control formula visibility with `style.setHidden()`. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Protected Cell"); const style = new Style(); style.setLocked(true); style.setHidden(false); worksheet.getCell2("A1").setStyle(style); workbook.protect(true, "password"); await workbook.save("protected.xlsx"); ``` ### Column and Row Sizing Set column widths with `worksheet.setColumnWidth()` and row heights with `worksheet.setRowHeight()`. Hide rows with `worksheet.setRowHidden()`. These settings persist in the saved XLSX file. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Wide Column"); worksheet.setColumnWidth(0, 30); worksheet.setRowHeight(0, 25); await workbook.save("sized.xlsx"); ``` --- ## Quick Start Build the package from source: Build a styled workbook with validation and auto-filter: ```typescript import { Workbook, Style, DataValidation } from "excel-cells"; const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Status"); worksheet.putValue("B1", "Value"); const headerStyle = new Style(); headerStyle.setBold(true); worksheet.getCell2("A1").setStyle(headerStyle); worksheet.getCell2("B1").setStyle(headerStyle); const validation = new DataValidation(); validation.type = "list"; validation.formula1 = '"Active,Inactive,Pending"'; worksheet.addDataValidation(validation, "A2:A20"); worksheet.setAutoFilter("A1:B20"); await workbook.save("managed.xlsx"); ``` --- ## Open Source & Licensing Aspose.Cells FOSS for TypeScript is released under the MIT license. The source code is available on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-TypeScript). Commercial use is permitted under the MIT license terms. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/typescript/) - [API Reference](https://reference.aspose.org/cells/typescript/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Cells for TypeScript — Enterprise Product](https://products.aspose.com/cells/) --- # Introducing Aspose.Cells FOSS for TypeScript URL: https://blog.aspose.org/cells/typescript/typescript-excel-xlsx-library/ Aspose.Cells FOSS for TypeScript is a free, MIT-licensed library for creating, reading, modifying, and exporting Excel spreadsheets to XLSX, CSV, JSON, Markdown, and HTML from TypeScript and Node.js applications. --- Product: Aspose.Cells Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/cells/typescript/typescript-excel-xlsx-library/ --- # Introducing Aspose.Cells FOSS for TypeScript ## Introduction Aspose.Cells FOSS for TypeScript is a free, open-source library that lets developers create, read, modify, and export Excel spreadsheets directly from TypeScript applications. The library is MIT-licensed and has no dependency on Microsoft Office or any native runtime -- it runs identically on Windows, Linux, and macOS. The library provides a clean API built around `Workbook`, `Worksheet`, `Cell`, and `Style` classes. Developers can write cell values, set formulas, apply font and fill styling, add charts and shapes, configure data validation and auto-filters, and export to multiple formats including XLSX, CSV, JSON, Markdown, and HTML. Install with a single command and start building spreadsheet automation pipelines, report generators, and data export tools without any Office dependency. --- ## Key Features ### Read and Write XLSX Files Load existing workbooks with `Workbook.load()` and save with `workbook.save()`. Cell values, formulas, and styles round-trip through XLSX without loss. The `WorksheetCollection` class supports creating, removing, and reordering worksheets. ```typescript const workbook = await Workbook.load("input.xlsx"); const worksheet = workbook.worksheets[0]!; console.log("A1:", worksheet.getCell(0, 0)?.value); worksheet.putValue("B1", "Updated"); await workbook.save("output.xlsx"); ``` ### Cell Values and Formulas Write integers, decimals, and strings with `worksheet.putValue()`. Set formulas with `cell.setFormula()` -- the formula string is stored verbatim in the XLSX file and evaluated by Excel or LibreOffice when opened. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", 42); worksheet.putValue("A2", 3.14159); worksheet.putValue("A3", "Hello World"); const cellA4 = worksheet.getCell2("A4"); cellA4.setFormula("=SUM(A1:A2)"); await workbook.save("formulas.xlsx"); ``` ### Font and Fill Styling Apply bold, italic, font size, font name, and font color using the `Style` class. Each cell can have its own independent style applied via `cell.setStyle()`. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; const style = new Style(); style.setFontName("Arial"); style.setFontSize(14); style.setBold(true); style.setFontColor("FF0000"); const cell = worksheet.getCell2("A1"); cell.putValue("Styled Text"); cell.setStyle(style); await workbook.save("styled.xlsx"); ``` ### Multi-Format Export Export workbooks to CSV, JSON, Markdown, and HTML using dedicated methods on `Workbook`: `toCsv()`, `toJson()`, `toMarkdown()`, and `toHtml()`. Alternatively, pass a file path with the desired extension to `workbook.save()`. ```typescript const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Name"); worksheet.putValue("B1", "Age"); worksheet.putValue("A2", "Alice"); worksheet.putValue("B2", 25); await workbook.save("data.csv"); await workbook.save("data.json"); await workbook.save("data.md"); ``` --- ## Quick Start Build the package from source: Create a workbook, write data, apply styling, and save: ```typescript import { Workbook, Style } from "excel-cells"; const workbook = new Workbook(); const worksheet = workbook.worksheets[0]!; worksheet.putValue("A1", "Product"); worksheet.putValue("B1", "Revenue"); worksheet.putValue("A2", "Widget"); worksheet.putValue("B2", 42000); worksheet.putValue("A3", "Gadget"); worksheet.putValue("B3", 31500); const headerStyle = new Style(); headerStyle.setBold(true); headerStyle.setFontSize(12); worksheet.getCell2("A1").setStyle(headerStyle); worksheet.getCell2("B1").setStyle(headerStyle); worksheet.setAutoFilter("A1:B3"); await workbook.save("report.xlsx"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |----------|-------------|------|-------| | XLSX | .xlsx | ✓ | ✓ | | CSV | .csv | — | ✓ | | JSON | .json | — | ✓ | | Markdown | .md | — | ✓ | | HTML | .html | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Cells FOSS for TypeScript is released under the MIT license. The source code is hosted on [GitHub](https://github.com/aspose-cells-foss/Aspose.Cells-FOSS-for-TypeScript) and accepts bug reports and pull requests. Commercial use is permitted under the MIT license terms. --- ## Getting Started - [Getting Started](https://docs.aspose.org/cells/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/cells/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/cells/typescript/) - [API Reference](https://reference.aspose.org/cells/typescript/) ## Related Resources - [Aspose.Cells — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Email FOSS for C++ URL: https://blog.aspose.org/email/cpp/ --- Product: Aspose.Email Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/email/cpp/ --- # Aspose.Email FOSS for C++ ## Related Resources - [Aspose.Email for C++ — Enterprise Product](https://products.aspose.com/email/cpp/) ## Related Topics - [Reading Outlook MSG Files in C++ Without Dependencies](https://blog.aspose.org/email/cpp/aspose-email-foss-cpp-outlook-msg-reader/) - [Introducing Aspose.Email FOSS for C++](https://blog.aspose.org/email/cpp/introducing-email-foss-cpp/) --- # Reading Outlook MSG Files in C++ Without Dependencies URL: https://blog.aspose.org/email/cpp/aspose-email-foss-cpp-outlook-msg-reader/ Aspose.Email FOSS for C++ is a compiled, zero-dependency library that reads, creates, and converts Outlook MSG files entirely in C++17. It supports MSG, EML (RFC 5322), and CFB (Compound File Binary) formats via the mapi_message, msg_reader, and cfb_reader classes. --- Product: Aspose.Email Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/email/cpp/aspose-email-foss-cpp-outlook-msg-reader/ --- # Reading Outlook MSG Files in C++ Without Dependencies ## Introduction This post walks through the core workflow for reading, creating, and converting Outlook MSG files in C++ using Aspose.Email FOSS — a pure C++17, MIT-licensed library with no external dependencies and no COM. You will learn how to read an existing MSG file, inspect its properties, create a new message programmatically, and round-trip between MSG and EML formats. The library builds identically on Linux, macOS, and Windows. It is distributed as source via GitHub and integrates by cloning the repository and adding it as a CMake subdirectory — no package manager registration is required. --- ## Key Features ### Read Existing MSG Files Use `msg_reader` to open a `.msg` file and `msg_document` to access its structured content. Both classes live in the `aspose::email::foss::msg` namespace. ```cpp #include "aspose/email/foss/msg/msg_reader.hpp" #include "aspose/email/foss/msg/msg_document.hpp" #include namespace aef = aspose::email::foss; auto reader = aef::msg::msg_reader::from_file(std::filesystem::path("message.msg")); auto document = aef::msg::msg_document::from_reader(reader); ``` `msg_reader` also has a `from_stream` overload for reading from an `std::istream`, which is useful in server-side or pipeline contexts where files are not present on disk. ### Create Messages Programmatically `mapi_message::create` produces a new in-memory message with a subject and body. You can then set sender details, add recipients, and attach binary or text payloads before saving. ```cpp #include "aspose/email/foss/msg/mapi_message.hpp" namespace aef = aspose::email::foss; auto msg = aef::msg::mapi_message::create( "Quarterly status update", "Hello team,\n\nPlease find the rollout summary attached.\n\nRegards"); msg.set_sender_name("Build Agent"); msg.set_sender_email_address("build.agent@example.com"); msg.add_recipient("alice@example.com", "Alice Example"); msg.save(std::filesystem::path("output.msg")); ``` ### Convert MSG to EML `mapi_message` supports direct MSG-to-EML conversion through the `save_to_eml` method. EML output conforms to RFC 5322 (MIME), making it compatible with any standard mail client or processing pipeline. ```cpp auto loaded = aef::msg::mapi_message::from_file( std::filesystem::path("message.msg"), /*strict=*/false); // Save as EML to a file loaded.save_to_eml(std::filesystem::path("message.eml")); // Or capture as bytes std::vector eml_bytes = loaded.save_to_eml(); ``` ### Load from EML The reverse direction is equally straightforward: `load_from_eml` reads an EML file and produces a `mapi_message` in memory, which can then be saved back to MSG. ```cpp auto from_eml = aef::msg::mapi_message::load_from_eml( std::filesystem::path("message.eml")); from_eml.save(std::filesystem::path("restored.msg")); ``` ### Low-Level CFB Access For advanced use cases — such as reading raw MAPI properties not exposed by the high-level API — `cfb_reader` gives direct access to the Compound File Binary container that underpins the MSG format. ```cpp #include "aspose/email/foss/cfb/cfb_reader.hpp" namespace aef = aspose::email::foss; auto cfb = aef::cfb::cfb_reader::from_file(std::filesystem::path("message.msg")); auto storage_ids = cfb.storage_ids(); auto stream_ids = cfb.stream_ids(); ``` --- ## Quick Start ### Step 1 — Clone and Add as Subdirectory Clone the repository into your project's source tree or a vendor directory: ```bash git clone https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Cpp.git ``` Then reference it in your project `CMakeLists.txt` using `add_subdirectory`: ```cmake cmake_minimum_required(VERSION 3.26) project(my_project) add_subdirectory(Aspose.Email-FOSS-for-Cpp) add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE AsposeEmailFoss::AsposeEmailFoss) ``` ### Step 2 — Include and Use Include the `mapi_message` header and write a simple program to create a MSG file and convert it to EML: ```cpp #include #include "aspose/email/foss/msg/mapi_message.hpp" namespace aef = aspose::email::foss; int main() { // Create a message auto msg = aef::msg::mapi_message::create("Hello from C++", "Body text here"); msg.save(std::filesystem::path("hello.msg")); // Round-trip to EML auto loaded = aef::msg::mapi_message::from_file( std::filesystem::path("hello.msg"), false); loaded.save_to_eml(std::filesystem::path("hello.eml")); std::cout **CFB note.** MSG files are stored internally in Compound File Binary format. The library reads CFB structures transparently when loading `.msg` files; no separate CFB format class is required. --- ## Open Source & Licensing Aspose.Email FOSS for C++ is released under the MIT license. The full source is available on GitHub at [aspose-email-foss/Aspose.Email-FOSS-for-Cpp](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Cpp). Commercial use is permitted without royalties. The library has no runtime dependencies beyond a C++17 compiler and CMake 3.26 or later. --- ## Getting Started - [Getting Started](https://docs.aspose.org/email/cpp/getting-started/) - [Installation Guide](https://docs.aspose.org/email/cpp/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/email/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/email/cpp/) - [API Reference](https://reference.aspose.org/email/cpp/) ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Email for C++ — Enterprise Product](https://products.aspose.com/email/cpp/) --- # Introducing Aspose.Email FOSS for C++ URL: https://blog.aspose.org/email/cpp/introducing-email-foss-cpp/ Aspose.Email FOSS for C++ is a free, MIT-licensed C++17 library for reading, creating, and converting Outlook MSG files, RFC 5322 EML messages, and the Compound File Binary (CFB) containers that MSG is built on. It has no external runtime dependencies and builds into any project as a CMake subdirectory, centered on the mapi_message, msg_reader, and cfb_reader classes. --- Product: Aspose.Email Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/email/cpp/introducing-email-foss-cpp/ --- # Introducing Aspose.Email FOSS for C++ ## Introduction Aspose.Email FOSS for C++ is a new open-source library for reading, creating, and converting Outlook MSG files, RFC 5322 EML messages, and the Compound File Binary (CFB) containers that the MSG format is built on. It is written in C++17, has no external runtime dependencies, and builds on Linux, macOS, and Windows through CMake — there is no COM dependency and no platform-specific code path. Outlook MSG files show up constantly in enterprise integration work — archival pipelines, migration tools, compliance exports — but reading them without Outlook itself has usually meant COM automation on Windows or a commercial library. Aspose.Email FOSS for C++ gives you a portable alternative: a high-level `mapi_message` class for everyday message reading and creation, plus lower-level `msg_reader`, `msg_document`, and `cfb_reader` classes for direct access to the underlying container format when you need it. The library is distributed as C++17 source under the MIT license and added to a project as a CMake subdirectory, exposing the AsposeEmailFoss target — no package manager registration and no prebuilt binaries are required. --- ## Key Features ### Read Outlook MSG Files Open a `.msg` file with `msg_reader::from_file()` or `msg_reader::from_stream()`. To access a message's storages and streams directly, wrap the reader in a `msg_document` with `msg_document::from_reader()`. ```cpp #include "aspose/email/foss/msg/msg_reader.hpp" #include "aspose/email/foss/msg/msg_document.hpp" #include namespace aef = aspose::email::foss; auto reader = aef::msg::msg_reader::from_file( std::filesystem::path("message.msg"), /*strict=*/false); auto document = aef::msg::msg_document::from_reader(reader); ``` ### Create Messages Programmatically `mapi_message::create()` builds a new in-memory message from a subject and body. Set the sender, add recipients, and attach binary or text payloads before saving with `save()`. ```cpp #include "aspose/email/foss/msg/mapi_message.hpp" #include namespace aef = aspose::email::foss; auto message = aef::msg::mapi_message::create( "Quarterly status update", "Hello team,\n\nRollout summary attached."); message.set_sender_name("Build Agent"); message.set_sender_email_address("build.agent@example.com"); message.add_recipient("alice@example.com", "Alice Example"); message.add_recipient("carol@example.com", "Carol Example", aef::msg::mapi_message::recipient_type_cc); message.add_attachment("report.txt", std::vector{'o', 'k'}, "text/plain"); message.save(std::filesystem::path("output.msg")); ``` ### Convert Between MSG and EML `mapi_message::save_to_eml()` writes the current message as an RFC 5322 EML file, and `mapi_message::load_from_eml()` reads one back. Both directions preserve the subject, sender, recipients, and attachments, so a message can move between MSG and EML without Outlook. ```cpp auto message = aef::msg::mapi_message::from_file( std::filesystem::path("message.msg"), /*strict=*/false); message.save_to_eml(std::filesystem::path("message.eml")); auto restored = aef::msg::mapi_message::load_from_eml(std::filesystem::path("message.eml")); restored.save(std::filesystem::path("restored.msg")); ``` ### Inspect Message Properties and Attachments A loaded `mapi_message` exposes its standard header fields directly — `subject()`, `sender_name()`, `sender_email_address()`, `message_class()`, and `internet_message_id()` — along with `recipients()` and `attachments()` as vectors of `mapi_recipient` and `mapi_attachment`. For MAPI fields with no dedicated accessor, `get_property_value()` reads any property by its `common_message_property_id` and `property_type_code`. ```cpp #include "aspose/email/foss/msg/mapi_message.hpp" #include "aspose/email/foss/msg/common_message_property_id.hpp" #include "aspose/email/foss/msg/property_type_code.hpp" #include namespace aef = aspose::email::foss; template constexpr auto to_underlying(E value) noexcept { return static_cast>(value); } auto message = aef::msg::mapi_message::from_file( std::filesystem::path("message.msg"), /*strict=*/false); std::cout \n"; std::cout namespace aef = aspose::email::foss; auto cfb = aef::cfb::cfb_reader::from_file(std::filesystem::path("message.msg")); std::cout #include #include namespace aef = aspose::email::foss; int main() { auto message = aef::msg::mapi_message::create("Hello from C++", "Body text here"); message.set_sender_name("Alice"); message.set_sender_email_address("alice@example.com"); message.add_recipient("bob@example.com", "Bob"); message.add_attachment("note.txt", std::vector{'a', 'b', 'c'}, "text/plain"); message.save(std::filesystem::path("hello.msg")); auto loaded = aef::msg::mapi_message::from_file( std::filesystem::path("hello.msg"), /*strict=*/false); loaded.save_to_eml(std::filesystem::path("hello.eml")); return 0; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Outlook Message (MSG) | `.msg` | ✓ | ✓ | | EML (RFC 5322 / MIME) | `.eml` | ✓ | ✓ | | Compound File Binary (CFB) | `.cfb` | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Email FOSS for C++ is released under the MIT license. The full source is available at [aspose-email-foss/Aspose.Email-FOSS-for-Cpp](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Cpp), and commercial use is permitted without royalties. The library has no runtime dependencies beyond a C++17 compiler and CMake 3.26 or later. --- ## Getting Started - [Getting Started](https://docs.aspose.org/email/cpp/getting-started/) - [Installation Guide](https://docs.aspose.org/email/cpp/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/email/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/email/cpp/) - [API Reference](https://reference.aspose.org/email/cpp/) ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Email for C++ — Enterprise Product](https://products.aspose.com/email/cpp/) --- # Aspose.Email FOSS for .NET URL: https://blog.aspose.org/email/net/ --- Product: Aspose.Email Platform: net Page Type: index Canonical URL: https://blog.aspose.org/email/net/ --- # Aspose.Email FOSS for .NET ## Related Topics - [Aspose.Email FOSS for .NET — Key Features](https://blog.aspose.org/email/net/dotnet-mapi-cfb-eml-api/) - [Introducing Aspose.Email FOSS for .NET](https://blog.aspose.org/email/net/dotnet-outlook-msg-eml-library/) - [Email Message Parsing in .NET with Aspose.Email FOSS](https://blog.aspose.org/email/net/email-message-parsing-net/) --- # Aspose.Email FOSS for .NET — Key Features URL: https://blog.aspose.org/email/net/dotnet-mapi-cfb-eml-api/ A deep dive into the key features of Aspose.Email FOSS for .NET: high-level MapiMessage API, CFB container read/write, EML/MIME conversion, typed MAPI property access, and embedded message attachments — all in C# with no Microsoft Outlook dependency. --- Product: Aspose.Email Platform: net Page Type: index Canonical URL: https://blog.aspose.org/email/net/dotnet-mapi-cfb-eml-api/ --- # Aspose.Email FOSS for .NET — Key Features ## Introduction Aspose.Email FOSS for .NET is a MIT-licensed, dependency-free C# library for working with Outlook MSG files, Compound File Binary (CFB) containers, and EML messages. This post walks through each major feature area with working code examples drawn directly from the library's test suite — every class name and method signature shown here is verified against the [source repository](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-.Net). Install with a single command — no Microsoft Outlook, no COM interop, no native libraries: --- ## Key Features ### Read and Inspect MSG Files `MapiMessage.FromStream()` and `MapiMessage.FromFile()` open any Outlook `.msg` file and expose its full contents: subject, plain-text body, HTML body, sender name, sender email address, delivery time, internet message ID, recipients, and attachments. No Outlook installation is required — the entire MSG and CFB layer is implemented in managed C#. ```csharp using System.IO; using Aspose.Email.Foss.Msg; using var stream = File.OpenRead("sample.msg"); var message = MapiMessage.FromStream(stream); Console.WriteLine(message.Subject); Console.WriteLine(message.SenderEmailAddress); Console.WriteLine(message.Body); foreach (var recipient in message.Recipients) Console.WriteLine($"To: {recipient.EmailAddress}"); foreach (var attachment in message.Attachments) Console.WriteLine($"Attachment: {attachment.Filename} ({attachment.MimeType})"); ``` ### Create MSG Files from Scratch `MapiMessage.Create()` builds a complete email in memory. Set `SenderName`, `SenderEmailAddress`, `HtmlBody`, `InternetMessageId`, and `MessageDeliveryTime` as properties after creation, then add recipients with `AddRecipient()` and file or stream attachments with `AddAttachment()`. Serialize with `message.Save()` — returns a `byte[]` or writes directly to a path or `Stream`. ```csharp using System.IO; using Aspose.Email.Foss.Msg; var message = MapiMessage.Create("Hello", "Body"); message.SenderName = "Alice"; message.SenderEmailAddress = "alice@example.com"; message.HtmlBody = "Body"; message.InternetMessageId = ""; message.MessageDeliveryTime = new DateTime(2024, 1, 2, 3, 4, 5, DateTimeKind.Utc); message.AddRecipient("bob@example.com", "Bob"); message.AddAttachment("note.txt", "abc"u8.ToArray(), "text/plain"); using var output = File.Create("hello.msg"); message.Save(output); ``` ### Convert EML to MSG (and Back) `MapiMessage.LoadFromEml()` accepts a file path, a `Stream`, or a `byte[]` containing a standard RFC 5322 / MIME message. The built-in MIME parser preserves subject, plain-text body, HTML body, sender, recipients, and all attachments — including inline images with `Content-ID` headers. `SaveToEml()` serializes back to MIME for full EML ↔ MSG round-trips without any external MIME library. ```csharp using System.IO; using Aspose.Email.Foss.Msg; using var input = File.OpenRead("message.eml"); var message = MapiMessage.LoadFromEml(input); // Inspect fields parsed from MIME headers Console.WriteLine(message.Subject); Console.WriteLine(message.SenderEmailAddress); Console.WriteLine(message.HtmlBody); // Save as MSG for Outlook-compatible storage using var msgOutput = File.Create("message.msg"); message.Save(msgOutput); // Round-trip back to EML using var emlOutput = File.Create("roundtrip.eml"); message.SaveToEml(emlOutput); ``` ### Embedded Message Attachments An MSG file can contain another MSG file as an attachment — a common pattern in forwarded email chains. `AddEmbeddedMessageAttachment()` attaches a `MapiMessage` object as a nested `.msg` attachment. When reading, `MapiAttachment.IsEmbeddedMessage` signals the embedded type and `EmbeddedMessage` exposes the nested `MapiMessage` directly. ```csharp using System.IO; using Aspose.Email.Foss.Msg; var parent = MapiMessage.Create("Outer", "Parent body"); var child = MapiMessage.Create("Inner", "Child body"); child.SenderEmailAddress = "inner@example.com"; parent.AddEmbeddedMessageAttachment(child, "inner.msg"); parent.Save("outer.msg"); var loaded = MapiMessage.FromFile("outer.msg"); var attachment = loaded.Attachments[0]; if (attachment.IsEmbeddedMessage) Console.WriteLine($"Embedded subject: {attachment.EmbeddedMessage!.Subject}"); ``` ### CFB Container Read and Write Outlook MSG files are built on the Compound File Binary (CFB) format — a hierarchical binary container similar to a FAT filesystem. `CfbReader` exposes the full directory tree: iterate storages and streams with `IterChildren()`, navigate to specific entries by path chain with `ResolvePath()`, and read raw stream bytes with `GetStreamData()`. `CfbWriter.ToBytes()` serializes a `CfbDocument` to bytes — useful for constructing custom CFB documents or verifying lossless round-trips. ```csharp using System.Text; using Aspose.Email.Foss.Cfb; // Build a CFB document from scratch var document = new CfbDocument(); document.Root.AddStream(new CfbStream("ReadMe", Encoding.UTF8.GetBytes("hello"))); var storage = document.Root.AddStorage(new CfbStorage("DataStore")); storage.AddStream(new CfbStream("Payload", Encoding.UTF8.GetBytes("content"))); byte[] bytes = CfbWriter.ToBytes(document); // Read it back using var reader = new CfbReader(bytes); var entry = reader.ResolvePath(["DataStore", "Payload"]); if (entry is not null) { var data = reader.GetStreamData(entry.StreamId); Console.WriteLine(Encoding.UTF8.GetString(data)); // "content" } ``` ### Typed MAPI Property Access `MapiPropertyCollection` provides typed MAPI property access for any MSG or storage object. The `CommonMessagePropertyId` enum covers all standard MAPI property identifiers — `Subject`, `Body`, `BodyHtml`, `SenderName`, `SenderEmailAddress`, `MessageDeliveryTime`, `InternetMessageId`, and attachment properties including `AttachFilename`, `AttachMimeTag`, and `AttachContentId`. Use `SetProperty()` and `GetPropertyValue()` to read and write arbitrary properties beyond the named convenience fields on `MapiMessage`. ```csharp using Aspose.Email.Foss.Msg; var message = MapiMessage.FromFile("sample.msg"); // Typed convenience properties Console.WriteLine(message.Subject); Console.WriteLine(message.SenderName); Console.WriteLine(message.MessageDeliveryTime); // Iterate all MAPI property keys foreach (var key in message.IterPropertyKeys()) Console.WriteLine($"0x{(ushort)key.PropertyId:X4} / {key.PropertyType}"); ``` --- ## Quick Start ```csharp using System.IO; using Aspose.Email.Foss.Msg; // Read an MSG file using var stream = File.OpenRead("sample.msg"); var message = MapiMessage.FromStream(stream); Console.WriteLine(message.Subject); Console.WriteLine(message.SenderEmailAddress); foreach (var recipient in message.Recipients) Console.WriteLine($"To: {recipient.EmailAddress}"); foreach (var attachment in message.Attachments) Console.WriteLine($"Attachment: {attachment.Filename} ({attachment.MimeType})"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Compound File Binary | `.cfb` | ✓ | ✓ | | Outlook Message | `.msg` | ✓ | ✓ | | MIME / EML | `.eml` | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Email FOSS for .NET is released under the **MIT license**. Use it freely in personal, commercial, and open-source projects with no usage restrictions. The source code is available at [github.com/aspose-email-foss/Aspose.Email-FOSS-for-.Net](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-.Net). --- ## Getting Started - [Getting Started](https://docs.aspose.org/email/net/getting-started/) - [Developer Guide](https://docs.aspose.org/email/net/developer-guide/) - [KB Articles](https://kb.aspose.org/email/net/) - [API Reference](https://reference.aspose.org/email/net/) ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Email for .NET — Enterprise Product](https://products.aspose.com/email/net/) --- # Introducing Aspose.Email FOSS for .NET URL: https://blog.aspose.org/email/net/dotnet-outlook-msg-eml-library/ Aspose.Email FOSS for .NET is a free, MIT-licensed C# library for reading, creating, and processing Outlook MSG files, Compound File Binary (CFB) containers, and EML messages. No Microsoft Outlook or native dependencies required. Targets .NET 8.0+. --- Product: Aspose.Email Platform: net Page Type: index Canonical URL: https://blog.aspose.org/email/net/dotnet-outlook-msg-eml-library/ --- # Introducing Aspose.Email FOSS for .NET ## Introduction Aspose.Email FOSS for .NET is a free, open-source C# library that lets you work with Outlook MSG files, Compound File Binary (CFB) containers, and EML messages directly in your .NET application — no Microsoft Outlook, no COM interop, and no native libraries required. Distribute it as a single NuGet package and it runs identically on Windows, Linux, macOS, Docker containers, and serverless functions. The library solves a recurring problem in enterprise and integration work: Outlook `.msg` files are produced by millions of business users, but parsing them without Outlook has historically required COM automation or expensive commercial libraries. Aspose.Email FOSS for .NET provides full read/write support for MSG, the underlying CFB binary container, and the EML/MIME format — all under the MIT license with no usage restrictions. Whether you are building an email archival pipeline, a migration tool, an attachment extractor, or an automated MSG generator, this library gives you direct, low-level access to every byte of the email format alongside a high-level `MapiMessage` API that lets you get started in minutes. --- ## Key Features ### Read Outlook MSG Files Open any `.msg` file from a path or stream with `MsgReader.FromFile()` or `MsgReader.FromStream()`. Access the complete MAPI property stream, recipient records, and attachment sub-storages at the raw byte level via `MsgStorage` and `MsgStream`. ```csharp using System.IO; using Aspose.Email.Foss.Msg; using var stream = File.OpenRead("sample.msg"); var message = MapiMessage.FromStream(stream); Console.WriteLine(message.Subject); ``` ### Create MSG Files from Scratch Build a complete email programmatically using `MapiMessage.Create()`. Set the subject, plain-text body, HTML body, sender name, sender email address, delivery time, and internet message ID, then add recipients with `AddRecipient()` and attachments with `AddAttachment()`. Serialize with `message.Save()`. ```csharp using System.IO; using Aspose.Email.Foss.Msg; var message = MapiMessage.Create("Hello", "Body"); message.SenderName = "Alice"; message.SenderEmailAddress = "alice@example.com"; message.AddRecipient("bob@example.com", "Bob"); using var attachmentStream = new MemoryStream("abc"u8.ToArray()); message.AddAttachment("note.txt", attachmentStream, "text/plain"); using var output = File.Create("hello.msg"); message.Save(output); ``` ### Convert EML to MSG (and Back) Load a standard RFC 5322 `.eml` file into a `MapiMessage` with `MapiMessage.LoadFromEml()`, then save it as an Outlook `.msg` file — or reverse the process with `MapiMessage.SaveToEml()`. The built-in MIME parser preserves subject, body, HTML body, sender, recipients, and attachments through full EML ↔ MSG round-trips. ```csharp using System.IO; using Aspose.Email.Foss.Msg; using var input = File.OpenRead("message.eml"); var message = MapiMessage.LoadFromEml(input); using var msgOutput = File.Create("message.msg"); message.Save(msgOutput); using var emlOutput = File.Create("roundtrip.eml"); message.SaveToEml(emlOutput); ``` ### Low-Level CFB Container Access Outlook MSG files are built on the Compound File Binary (CFB) format — a hierarchical binary container similar to a filesystem. `CfbReader` exposes the full directory tree: iterate storages and streams with `IterStorages()`, `IterStreams()`, and `IterChildren()`, navigate to specific entries by path with `ResolvePath()`, and read raw stream bytes with `GetStreamData()`. `CfbWriter` lets you construct and serialize a CFB document from scratch. Create a `CfbDocument`, attach `CfbStorage` and `CfbStream` nodes, and call `CfbWriter.ToBytes()` or `CfbWriter.WriteFile()` to serialize. ### MAPI Property and Attachment Access The `MapiPropertyCollection` class provides typed MAPI property access for any MSG or storage object: use `Get()`, `Set()`, `Add()`, and `Remove()` with standard `CommonMessagePropertyId` or `PropertyTypeCode` enum values. Access attachment metadata and binary data via `MapiAttachment` properties: `Filename`, `MimeType`, `ContentId`, and `Data`. --- ## Quick Start Install the package: Read a subject from an MSG file: ```csharp using System.IO; using Aspose.Email.Foss.Msg; using var stream = File.OpenRead("sample.msg"); var message = MapiMessage.FromStream(stream); Console.WriteLine(message.Subject); Console.WriteLine(message.SenderEmailAddress); foreach (var recipient in message.Recipients) Console.WriteLine($"To: {recipient.EmailAddress}"); foreach (var attachment in message.Attachments) Console.WriteLine($"Attachment: {attachment.Filename} ({attachment.MimeType})"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Compound File Binary | `.cfb` | ✓ | ✓ | | Outlook Message | `.msg` | ✓ | ✓ | | MIME / EML | `.eml` | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Email FOSS for .NET is released under the **MIT license**. You may use it freely in personal, commercial, and open-source projects with no usage restrictions. The source code is available at [github.com/aspose-email-foss/Aspose.Email-FOSS-for-.Net](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-.Net). --- ## Getting Started - [Getting Started](https://docs.aspose.org/email/net/getting-started/) - [Developer Guide](https://docs.aspose.org/email/net/developer-guide/) - [KB Articles](https://kb.aspose.org/email/net/) - [API Reference](https://reference.aspose.org/email/net/) ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) --- # Email Message Parsing in .NET with Aspose.Email FOSS URL: https://blog.aspose.org/email/net/email-message-parsing-net/ Learn how to parse Outlook MSG files and EML messages in C# using Aspose.Email FOSS for .NET. Extract subjects, senders, recipients, attachments, and MAPI properties with a free, MIT-licensed library targeting .NET 8.0+. --- Product: Aspose.Email Platform: net Page Type: index Canonical URL: https://blog.aspose.org/email/net/email-message-parsing-net/ --- # Email Message Parsing in .NET with Aspose.Email FOSS ## Introduction Parsing email messages programmatically is a common requirement for archival tools, compliance pipelines, and migration utilities. Outlook MSG files use the Compound File Binary (CFB) container format with MAPI property streams, while EML files follow the MIME standard. Both formats require careful handling of encodings, folded headers, and nested attachments. Aspose.Email FOSS for .NET is a free, MIT-licensed C# library that provides a complete read-write API for MSG and EML messages. It targets .NET 8.0+ and has no dependency on Microsoft Outlook or any native COM interop layer. The library is available as the `aspose.email.foss` NuGet package. This post walks through the message-parsing capabilities included in the library, from loading files off disk to extracting individual MAPI properties and converting between formats. --- ## What's Included ### Loading MSG Files The `MapiMessage` class is the primary entry point for working with Outlook MSG files. You can load a message from a file path or a stream, with an optional strict-validation flag that surfaces any structural issues found in the file. ```csharp // Load an MSG file from disk var message = MapiMessage.FromFile("meeting-invite.msg"); Console.WriteLine($"Subject: {message.Subject}"); Console.WriteLine($"From: {message.SenderName} "); Console.WriteLine($"Date: {message.MessageDeliveryTime}"); Console.WriteLine($"Recipients: {message.Recipients.Count}"); Console.WriteLine($"Attachments: {message.Attachments.Count}"); ``` The returned `MapiMessage` exposes typed properties for common fields including `Subject`, `Body`, `HtmlBody`, `SenderName`, `SenderEmailAddress`, `InternetMessageId`, and `MessageDeliveryTime`. ### Loading EML Messages EML files use the MIME format. `MapiMessage.LoadFromEml` accepts a file path, a `Stream`, or a `byte[]` and returns the same `MapiMessage` object, so you use one unified API regardless of the source format. ```csharp // Load from a file path var fromFile = MapiMessage.LoadFromEml("newsletter.eml"); // Load from a stream using var stream = File.OpenRead("newsletter.eml"); var fromStream = MapiMessage.LoadFromEml(stream); Console.WriteLine($"Subject: {fromStream.Subject}"); Console.WriteLine($"Body: {fromStream.Body?.Trim()}"); ``` The parser handles folded headers, Base64 and quoted-printable transfer encodings, and multi-recipient To/Cc fields. ### Working with Recipients and Attachments Once a message is loaded, recipients and attachments are available as strongly-typed collections. Each `MapiRecipient` carries `EmailAddress`, `DisplayName`, and `RecipientType` fields. Each `MapiAttachment` provides `Filename`, `Data`, `MimeType`, and `ContentId`. ```csharp var message = MapiMessage.FromFile("report.msg"); foreach (var recipient in message.Recipients) { Console.WriteLine($" {recipient.DisplayName} (type={recipient.RecipientType})"); } foreach (var attachment in message.Attachments) { Console.WriteLine($" {attachment.Filename} ({attachment.MimeType}, {attachment.Data.Length} bytes)"); File.WriteAllBytes(attachment.Filename!, attachment.Data); } ``` Embedded message attachments are also supported. When `MapiAttachment.IsEmbeddedMessage` is `true`, the `EmbeddedMessage` property returns a nested `MapiMessage` that you can inspect recursively. ### Accessing MAPI Properties For advanced scenarios, every message, recipient, and attachment exposes a `Properties` collection of type `MapiPropertyCollection`. You can read, add, and remove individual MAPI properties by their property ID and type code. ```csharp var message = MapiMessage.FromFile("custom-props.msg"); // Iterate all properties on the message foreach (var prop in message.Properties.IterProperties()) { Console.WriteLine($"Tag: 0x{prop.PropertyTag:X8}, Value: {prop.Value}"); } // Read a specific property var subject = message.Properties.Get( (ushort)CommonMessagePropertyId.Subject, (ushort)PropertyTypeCode.PtypString); ``` The `CommonMessagePropertyId` enum defines well-known MAPI property identifiers for core message semantics, body fields, transport headers, and attachment metadata. ### Converting Between MSG and EML A parsed message can be saved back in either format. `Save()` writes MSG bytes, while `SaveToEml()` produces MIME output. This makes format conversion straightforward. ```csharp // Load an EML and save as MSG var message = MapiMessage.LoadFromEml("incoming.eml"); message.Save("converted.msg"); // Load an MSG and save as EML var msg = MapiMessage.FromFile("outgoing.msg"); msg.SaveToEml("exported.eml"); ``` Both methods also accept a `Stream` parameter for in-memory processing without touching the file system. --- ## Quick Start Install the package from NuGet: Then parse your first message: ```csharp using Aspose.Email.Foss.Msg; // Load an MSG file var message = MapiMessage.FromFile("sample.msg"); Console.WriteLine($"Subject: {message.Subject}"); Console.WriteLine($"From: {message.SenderName} "); Console.WriteLine($"Date: {message.MessageDeliveryTime}"); Console.WriteLine($"Body length: {message.Body?.Length ?? 0} chars"); // List attachments foreach (var att in message.Attachments) Console.WriteLine($" Attachment: {att.Filename} ({att.Data.Length} bytes)"); // Convert to EML message.SaveToEml("sample.eml"); Console.WriteLine("Saved as EML."); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Outlook MSG | `.msg` | Yes | Yes | | MIME (EML) | `.eml` | Yes | Yes | | Compound File Binary | `.cfb` | Yes | Yes | --- ## Open Source & Licensing Aspose.Email FOSS for .NET is released under the MIT license. The full source code is available on GitHub at [aspose-email-foss/Aspose.Email-FOSS-for-.Net](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-.Net.git). Contributions, issues, and pull requests are welcome. --- ## Getting Started - [Developer Guide](https://docs.aspose.org/email/net/) — detailed documentation and walkthroughs - [Knowledge Base](https://kb.aspose.org/email/net/) — FAQs and how-to articles - [API Reference](https://reference.aspose.org/email/net/) — full class and method reference ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Email FOSS for Python URL: https://blog.aspose.org/email/python/ --- Product: Aspose.Email Platform: python Page Type: index Canonical URL: https://blog.aspose.org/email/python/ --- # Aspose.Email FOSS for Python Blog posts for Aspose.Email FOSS for Python — a free, MIT-licensed library for reading and writing MSG and CFB email files in Python. ## Related Resources - [Aspose.Email for Python — Enterprise Product](https://products.aspose.com/email/python/) ## Related Topics - [Email Message Parsing in Python with Aspose.Email FOSS](https://blog.aspose.org/email/python/email-message-parsing-python/) - [Introducing Aspose.Email FOSS for Python](https://blog.aspose.org/email/python/introducing-email-foss-python/) - [Key Features of Aspose.Email FOSS for Python](https://blog.aspose.org/email/python/python-mapi-msg-properties/) --- # Email Message Parsing in Python with Aspose.Email FOSS URL: https://blog.aspose.org/email/python/email-message-parsing-python/ Learn how to parse, read, and extract data from Outlook MSG files in Python using aspose-email-foss, a free MIT-licensed library with full MAPI property access. --- Product: Aspose.Email Platform: python Page Type: index Canonical URL: https://blog.aspose.org/email/python/email-message-parsing-python/ --- # Email Message Parsing in Python with Aspose.Email FOSS ## Introduction Parsing email messages programmatically is a common requirement for data migration, archival workflows, and compliance tools. Outlook MSG files use the Compound File Binary (CFB) container format with MAPI properties to encode message metadata, body content, recipients, and attachments. Working with this format in Python has traditionally required either commercial libraries or low-level binary manipulation. The `aspose-email-foss` package provides a pure-Python, MIT-licensed library for reading, creating, and converting Outlook MSG files. It exposes a high-level `MapiMessage` API for common tasks alongside lower-level `MsgReader` access for detailed inspection of the underlying CFB structure. The library requires Python 3.10 or later and has no native dependencies. Whether you need to extract the subject line and body from a batch of archived messages, enumerate attachments for indexing, or convert MSG files to standard RFC 5322 format, this library handles the binary parsing so you can focus on your application logic. --- ## What's Included ### Reading MSG Files with MapiMessage The `MapiMessage` class is the primary entry point for parsing Outlook MSG files. Open a file, access its properties, and close it cleanly with a context manager. ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("meeting-invite.msg") as message: print(f"Subject: {message.subject}") print(f"Body: {message.body[:200]}") print(f"HTML body available: {message.body_html is not None}") ``` The `from_file` method reads the CFB container, parses the MAPI property streams, and populates typed attributes. The `subject`, `body`, and `body_html` properties return decoded strings directly. ### Extracting Recipients Every MSG file stores recipient information in dedicated MAPI storages. The `MapiMessage.recipients` property returns a list of `MapiRecipient` objects with typed fields for display name, email address, and recipient type (TO, CC, or BCC). ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("team-update.msg") as message: for recipient in message.recipients: print( f"{recipient.display_name} " f"type={recipient.recipient_type}" ) ``` ### Working with Attachments The `iter_attachments_info` method yields `MapiAttachment` objects that provide the filename, raw bytes, MIME type, and optional Content-ID for inline images. ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("report.msg") as message: for att in message.iter_attachments_info(): print(f" {att.filename} ({att.mime_type}, {len(att.data)} bytes)") if att.content_id: print(f" inline content-id: {att.content_id}") ``` ### Accessing MAPI Properties For scenarios that require specific MAPI property values beyond the convenience attributes, use `get_property_value` with a `PropertyId` constant. This provides direct access to any property stored in the MSG file. ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("notification.msg") as message: sender = message.get_property_value(msg.PropertyId.SENDER_NAME) email = message.get_property_value(msg.PropertyId.SENDER_EMAIL_ADDRESS) delivery = message.get_property_value(msg.PropertyId.MESSAGE_DELIVERY_TIME) print(f"From: {sender} ") print(f"Delivered: {delivery}") ``` ### Iterating All Properties When you need to inspect every property in a message (for debugging, auditing, or migration), the `iter_properties` method yields `MapiProperty` objects with full tag and value information. ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("sample.msg") as message: for prop in message.iter_properties(): print( f"tag=0x{prop.property_tag:08X} " f"type=0x{prop.property_type:04X} " f"value={prop.value!r}" ) ``` ### Converting MSG to EML The `to_email_message` method converts a parsed MSG into a standard Python `email.message.EmailMessage` object. From there you can serialize the message to RFC 5322 (EML) format using the standard library. ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("archive.msg") as message: email_message = message.to_email_message() eml_bytes = email_message.as_bytes() with open("archive.eml", "wb") as f: f.write(eml_bytes) ``` Note that EML output uses Python's built-in `email` module for serialization. The library handles the MSG-to-MAPI-to-EmailMessage conversion; the standard library handles the RFC 5322 wire format. --- ## Quick Start Install the package from PyPI and parse your first MSG file in under 20 lines: ```python # Install: pip install aspose-email-foss>=26.3 from aspose.email_foss import msg # Create a new message message = msg.MapiMessage.create( "Project status update", "Hello team,\n\nPlease review the attached report.\n\nRegards", ) message.add_recipient("alice@example.com", display_name="Alice") message.add_attachment("notes.txt", b"meeting notes\n", mime_type="text/plain") message.save("status-update.msg") # Read it back and extract data with msg.MapiMessage.from_file("status-update.msg") as loaded: print(f"Subject: {loaded.subject}") print(f"Recipients: {len(loaded.recipients)}") for att in loaded.iter_attachments_info(): print(f"Attachment: {att.filename} ({len(att.data)} bytes)") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Outlook MSG | `.msg` | Yes | Yes | | Compound File Binary | `.cfb` | Yes | Yes | | EML (via conversion) | `.eml` | Yes (via `from_email_message`) | Yes (via `to_email_message`) | EML support works through conversion: `MapiMessage.from_email_message()` imports from a Python `email.message.EmailMessage` object, and `to_email_message()` exports back. Direct EML file parsing is not provided — the standard library handles the EML wire format. --- ## Open Source & Licensing Aspose.Email FOSS for Python is released under the MIT license. You are free to use, modify, and distribute the library in both commercial and non-commercial projects. The full source code is available on [GitHub](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Python.git). The library is a pure-Python implementation with no compiled extensions or native dependencies. It runs on any platform that supports Python 3.10 or later. --- ## Getting Started Explore more resources for working with Aspose.Email FOSS for Python: - [Developer Guide](https://docs.aspose.org/email/python/) — full documentation with tutorials and API walkthroughs - [Knowledge Base](https://kb.aspose.org/email/python/) — how-to articles and frequently asked questions - [API Reference](https://reference.aspose.org/email/python/) — complete class and method reference ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Email FOSS for Python URL: https://blog.aspose.org/email/python/introducing-email-foss-python/ Aspose.Email FOSS for Python provides a MIT-licensed library for reading, creating, and converting Outlook MSG files, EML messages, and Compound File Binary (CFB) storage structures. The library centers on the MapiMessage API with support for recipients, attachments, and typed MAPI properties. --- Product: Aspose.Email Platform: python Page Type: index Canonical URL: https://blog.aspose.org/email/python/introducing-email-foss-python/ --- # Introducing Aspose.Email FOSS for Python ## Introduction Aspose.Email FOSS for Python (`aspose-email-foss`) is a MIT-licensed Python library for working with Outlook MSG files, RFC-5322 EML messages, and Compound File Binary (CFB) storage structures. The library requires no native extensions and installs directly from PyPI. The library addresses a common Python development gap: reading and writing Outlook `.msg` files without requiring a running Outlook installation or proprietary SDK. It also exposes the full CFB container format that underlies `.msg` files, making it suitable for tasks ranging from message migration to storage inspection. The library ships with a typed API surface covering MAPI message construction, recipient and attachment management, property serialization, and CFB document round-trips. --- ## Key Features ### Creating and Serializing MSG Files `MapiMessage.create()` constructs a new MAPI message from a subject and body string. From there you can add typed properties, recipients, and binary attachments, then serialize the result to bytes using `to_bytes()`. ```python import datetime from aspose.email_foss.msg.mapi_message import MapiMessage, PropertyId message = MapiMessage.create("Quarterly Report", "Please review the attached report.") message.set_property(PropertyId.SENDER_NAME, "Alice") message.set_property(PropertyId.SENDER_EMAIL_ADDRESS, "alice@example.com") message.set_property( PropertyId.MESSAGE_DELIVERY_TIME, datetime.datetime(2026, 3, 15, 10, 30, tzinfo=datetime.timezone.utc), ) message.add_recipient("bob@example.com", display_name="Bob") message.add_attachment("report.pdf", b"%PDF-1.4 ...", mime_type="application/pdf") raw_bytes = message.to_bytes() ``` ### Reading Existing MSG Files `MapiMessage.from_file()` reads an existing `.msg` file from disk. You can also reconstruct a message from raw bytes by passing a `CFBReader` through `MsgReader` and `MsgDocument`. ```python from aspose.email_foss.msg.mapi_message import MapiMessage from aspose.email_foss.msg.reader import MsgReader, MsgDocument from aspose.email_foss.cfb.reader import CFBReader # Read from file path msg = MapiMessage.from_file("message.msg") print(msg.subject) # Or reconstruct from bytes msg2 = MapiMessage.from_msg_document( MsgDocument.from_reader(MsgReader(CFBReader(raw_bytes))) ) print(msg2.subject) for att in msg2.attachments: print(att.filename, len(att.data), "bytes") ``` ### Converting Between MAPI and RFC-5322 EML `MapiMessage.from_email_message()` converts a standard Python `email.message.EmailMessage` object into a MAPI message, preserving subject, recipients, body, and attachments. The reverse conversion uses `to_email_message()`. ```python from email.message import EmailMessage from aspose.email_foss.msg.mapi_message import MapiMessage # Build a standard Python email eml = EmailMessage() eml["Subject"] = "Meeting notes" eml["From"] = "alice@example.com" eml["To"] = "bob@example.com" eml.set_content("Notes from today's meeting.") # Convert to MAPI and serialize as .msg mapi = MapiMessage.from_email_message(eml) with open("meeting-notes.msg", "wb") as f: f.write(mapi.to_bytes()) # Round-trip back to EML recovered = mapi.to_email_message() print(recovered["Subject"]) ``` ### Compound File Binary (CFB) Storage The library includes a standalone CFB layer (`CFBReader`, `CFBWriter`, `CFBDocument`, `CFBStorage`, `CFBStream`) for reading and writing the Compound File Binary format independently of MAPI. This is useful for inspecting the raw storage structure of `.msg` files or for building custom compound file containers. ```python from aspose.email_foss.cfb.writer import CFBWriter, CFBDocument, CFBStorage, CFBStream from aspose.email_foss.cfb.reader import CFBReader # Build a CFB document with nested storage root = CFBStorage("Root Entry") root.add_stream(CFBStream("Metadata", b"meta-payload")) nested = root.add_storage(CFBStorage("Attachments")) nested.add_stream(CFBStream("Attachment1", b"binary-content")) doc = CFBDocument(root=root, major_version=3) data = CFBWriter.to_bytes(doc) # Read it back reader = CFBReader(data) entry = reader.resolve_path(["Attachments", "Attachment1"]) print(reader.get_stream_data(entry.stream_id)) ``` ### MAPI Property Access `iter_properties()` returns all MAPI properties on a message as `MapiProperty` objects. Named properties (PidLidTag and PidNameTag) are accessible via `MapiNamedProperty`. `MapiPropertyCollection` provides dict-like property access. ```python from aspose.email_foss.msg.mapi_message import MapiMessage msg = MapiMessage.from_file("message.msg") for prop in msg.iter_properties(): print(hex(prop.property_id), prop.property_type, repr(prop.value)[:60]) ``` --- ## Quick Start ```python import datetime from aspose.email_foss.msg.mapi_message import MapiMessage, PropertyId from aspose.email_foss.msg.reader import MsgReader, MsgDocument from aspose.email_foss.cfb.reader import CFBReader # Create a message message = MapiMessage.create("Hello", "This is the body.") message.set_property(PropertyId.SENDER_NAME, "Sender") message.set_property(PropertyId.SENDER_EMAIL_ADDRESS, "sender@example.com") message.add_recipient("recipient@example.com", display_name="Recipient") message.add_attachment("note.txt", b"attachment content", mime_type="text/plain") # Serialize and reload raw = message.to_bytes() reloaded = MapiMessage.from_msg_document( MsgDocument.from_reader(MsgReader(CFBReader(raw))) ) email = reloaded.to_email_message() print("Subject:", email["Subject"]) print("From:", email["From"]) ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | Msg | `.msg` | ✓ | ✓ | | CFB | `.cfb` | ✓ | ✓ | | eml | `.eml` | ✓ | ✓ | MSG files are read via `MapiMessage.from_file()` and `MsgReader`. EML is accessed through the `from_email_message()` / `to_email_message()` conversion bridge. CFB containers are handled directly by `CFBReader` and `CFBWriter`. --- ## Open Source & Licensing Aspose.Email FOSS for Python is released under the MIT License. The source is available on GitHub and the package is distributed via PyPI under the name `aspose-email-foss`. MIT licensing permits use in commercial applications without royalty or attribution requirements beyond license inclusion. --- ## Getting Started - [Getting Started](https://docs.aspose.org/email/python/getting-started/) - [Developer Guide](https://docs.aspose.org/email/python/developer-guide/) - [KB Articles](https://kb.aspose.org/email/python/) - [API Reference](https://reference.aspose.org/email/python/) ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) --- # Key Features of Aspose.Email FOSS for Python URL: https://blog.aspose.org/email/python/python-mapi-msg-properties/ A detailed look at the features in Aspose.Email FOSS for Python, including MAPI property access, recipient and attachment handling, MSG-to-EML conversion, CFB container round-trips, and structured error handling. --- Product: Aspose.Email Platform: python Page Type: index Canonical URL: https://blog.aspose.org/email/python/python-mapi-msg-properties/ --- # Key Features of Aspose.Email FOSS for Python ## Introduction Aspose.Email FOSS for Python goes beyond basic message creation. The library exposes the full depth of the MAPI property model, letting you read, write, and query individual properties by ID and type. It handles recipients, attachments, and embedded messages as first-class objects, and provides bidirectional conversion between the MSG binary format and Python's standard `email.message.EmailMessage`. At the container level, the CFB reader and writer give you deterministic control over Compound File Binary documents. You can traverse storage hierarchies, extract raw stream data, build new containers from scratch, and serialize them back to bytes. Both `CFBError` and `MsgError` provide structured exception handling for malformed input. This post walks through each capability with verified code examples drawn directly from the library's own test suite and example scripts. --- ## What's Included ### MAPI Property Access Every MSG file is built on MAPI properties. `MapiMessage` exposes `set_property()` and `get_property()` to work with properties by their `PropertyId` enum value. Use `iter_properties()` to enumerate all properties on a message, or `get_property_value()` for direct value retrieval with optional type decoding. ```python from aspose.email_foss import msg message = msg.MapiMessage.create("Status report", "Weekly update attached.") message.set_property(msg.PropertyId.SENDER_NAME, "Build Agent") message.set_property(msg.PropertyId.SENDER_EMAIL_ADDRESS, "build.agent@example.com") message.set_property(msg.PropertyId.DISPLAY_TO, "Alice Example; Bob Example") message.set_property(msg.PropertyId.DISPLAY_CC, "Carol Example") message.set_property(msg.PropertyId.DISPLAY_BCC, "Ops Archive") message.set_property( msg.PropertyId.TRANSPORT_MESSAGE_HEADERS, "X-Environment: production\nX-Workflow: weekly-report\n", ) message.save("report.msg") ``` To read properties back from an existing file: ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("report.msg") as loaded: print(f"Subject: {loaded.subject}") print(f"Body: {loaded.body}") for prop in loaded.iter_properties(): print(f"tag=0x{prop.property_tag:08X}") ``` ### Recipients and Attachments Add recipients with `add_recipient()`, specifying display name and recipient type (To, CC, or BCC). Attach files with `add_attachment()` using raw bytes and a MIME type. For nested messages, `add_embedded_message_attachment()` embeds a complete `MapiMessage` as a child object inside the parent. ```python from aspose.email_foss import msg message = msg.MapiMessage.create("Team update", "See attached notes.") message.add_recipient("alice@example.com", display_name="Alice Example") message.add_recipient( "carol@example.com", display_name="Carol Example", recipient_type=msg.RECIPIENT_TYPE_CC, ) message.add_recipient( "archive@example.com", display_name="Ops Archive", recipient_type=msg.RECIPIENT_TYPE_BCC, ) message.add_attachment("notes.txt", b"Meeting notes content\n", mime_type="text/plain") message.add_attachment("data.bin", b"\x00\x01\x02\x03", mime_type="application/octet-stream") message.save("team-update.msg") ``` To inspect attachments on an existing message: ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("team-update.msg") as loaded: for att in loaded.iter_attachments_info(): print(f"name={att.filename} mime={att.mime_type} size={len(att.data)}") print(f" embedded={att.is_embedded_message} storage={att.storage_name}") ``` ### MSG to EmailMessage Conversion The library converts in both directions between MSG and Python's `email.message.EmailMessage`. Use `to_email_message()` to produce a standards-compliant MIME object, or `from_email_message()` to import an existing `EmailMessage` into the MSG format. Convenience methods `to_email_bytes()` and `to_email_string()` serialize directly to bytes or text. ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("example.msg") as loaded: email_msg = loaded.to_email_message() print(f"content_type: {email_msg.get_content_type()}") print(f"is_multipart: {email_msg.is_multipart()}") print(f"headers: {len(email_msg)}") for key, value in email_msg.items(): print(f" {key}: {value}") body_part = email_msg.get_body(preferencelist=("plain", "html")) if body_part is not None: print(f"body: {body_part.get_content()[:200]}") ``` ### CFB Container Round-Trip Build and serialize Compound File Binary containers independently of the MSG layer. `CFBDocument.from_file()` loads an existing container into a mutable document model with `CFBStorage` and `CFBStream` nodes. `CFBWriter.write_file()` serializes the document back to disk deterministically. ```python from aspose.email_foss.cfb import CFBDocument, CFBReader, CFBWriter reader = CFBReader.from_file("container.cfb") document = CFBDocument.from_reader(reader) reader.close() output = CFBWriter.to_bytes(document) print(f"Serialized {len(output)} bytes") ``` ### Error Handling The library raises `CFBError` for malformed CFB content and `MsgError` for invalid MSG structure. `MapiMessage` also exposes a `validation_issues` property that returns a tuple of warning strings without raising an exception, letting you decide how strictly to handle non-conformant files. ```python from aspose.email_foss.cfb import CFBReader, CFBError from aspose.email_foss.msg import MsgReader, MsgError try: reader = CFBReader.from_file("corrupted.cfb") except CFBError as e: print(f"CFB parse error: {e}") try: reader = MsgReader.from_file("malformed.msg") except MsgError as e: print(f"MSG parse error: {e}") ``` --- ## Quick Start Load an existing MSG, read its metadata, and list attachments: ```python from aspose.email_foss import msg with msg.MapiMessage.from_file("inbox-message.msg") as message: print(f"Subject: {message.subject}") print(f"Body preview: {message.body[:200] if message.body else '(empty)'}") for att in message.iter_attachments_info(): print(f"Attachment: {att.filename} ({att.mime_type}, {len(att.data)} bytes)") issues = message.validation_issues if issues: print(f"Warnings: {issues}") ``` --- ## Supported Formats | Format | Import | Export | |--------|--------|--------| | MSG | Yes | Yes | | CFB | Yes | Yes | --- ## Open Source & Licensing Aspose.Email FOSS for Python is released under the [MIT License](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Python/blob/main/LICENSE). You may use it in personal, internal, and commercial projects without restriction. The source code is available on [GitHub](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Python). --- ## Getting Started - [Getting Started](https://docs.aspose.org/email/python/getting-started/) - [Developer Guide](https://docs.aspose.org/email/python/developer-guide/) - [KB Articles](https://kb.aspose.org/email/python/) - [API Reference](https://reference.aspose.org/email/python/) - [Introducing Aspose.Email FOSS for Python](https://blog.aspose.org/email/python/introducing-email-foss-python/) - [Source code on GitHub](https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Python) - [Package on PyPI](https://pypi.org/project/aspose-email-foss/) ## Related Resources - [Aspose.Email — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Font FOSS for Python URL: https://blog.aspose.org/font/python/ --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/ --- # Aspose.Font FOSS for Python ## Related Topics - [Brotli Compression in WOFF2 Fonts with Python using Aspose.Font FOSS](https://blog.aspose.org/font/python/brotli-font-compression-python/) - [Working with EOT Fonts in Python using Aspose.Font FOSS](https://blog.aspose.org/font/python/eot-fonts-in-python/) - [Working with CFF Fonts in Python using Aspose.Font FOSS](https://blog.aspose.org/font/python/font-cff-in-python/) - [Core Font Management in Python with Aspose.Font FOSS](https://blog.aspose.org/font/python/font-core-management-python/) - [Working with Font Tables in Python](https://blog.aspose.org/font/python/font-tables-in-python/) - [Introducing Aspose.Font FOSS for Python](https://blog.aspose.org/font/python/python-font-ttf-woff-library/) - [Working with TrueType Fonts in Python using Aspose.Font FOSS](https://blog.aspose.org/font/python/ttf-fonts-in-python/) - [Working with Type 1 Fonts in Python using Aspose.Font FOSS](https://blog.aspose.org/font/python/type1-fonts-in-python/) - [Working with WOFF and WOFF2 Web Fonts in Python using Aspose.Font FOSS](https://blog.aspose.org/font/python/woff-fonts-in-python/) --- # Brotli Compression in WOFF2 Fonts with Python using Aspose.Font FOSS URL: https://blog.aspose.org/font/python/brotli-font-compression-python/ Aspose.Font FOSS for Python bundles Brotli compression for WOFF2 web font production. Learn how WOFF2 uses Brotli internally, how to convert fonts to WOFF2 format, and how to use BrotliEncoder and BrotliDecoder for low-level binary data compression without any external dependencies. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/brotli-font-compression-python/ --- # Brotli Compression in WOFF2 Fonts with Python using Aspose.Font FOSS ## Introduction WOFF2 (Web Open Font Format 2) uses Brotli as its compression algorithm. Unlike WOFF 1 which uses zlib, WOFF2 applies Brotli to a pre-transformed glyph table representation, typically achieving 20-30% better compression than WOFF 1. This makes WOFF2 the preferred delivery format for web typography. Aspose.Font FOSS for Python handles all Brotli operations internally through its bundled `BrotliEncoder` and `BrotliDecoder` classes. No external `brotli`, `brotlicffi`, or similar package is needed. The standard font conversion API applies Brotli compression transparently when producing WOFF2 output. The library is distributed as `aspose-font` under the MIT License. --- ## Key Features ### Converting Fonts to WOFF2 The primary use of Brotli in Aspose.Font is automatic WOFF2 compression. Use `FontConverter.convert` with `FontType.WOFF2` to produce a Brotli-compressed web font: ```python from aspose_font.loader import FontLoader from aspose_font.converter import FontConverter from aspose_font import FontType from pathlib import Path # Load any supported format font = FontLoader.open("MyFont.ttf") # TTF, OTF, WOFF, EOT, CFF, TYPE1 # Convert to WOFF2 — Brotli applied internally woff2 = FontConverter.convert(font, FontType.WOFF2) output = woff2.to_bytes(FontType.WOFF2) Path("MyFont.woff2").write_bytes(output) print(f"WOFF2 output: {len(output)} bytes") ``` You can also convert from an existing WOFF 1 file to WOFF2 to upgrade compression: ```python from aspose_font.loader import FontLoader from aspose_font.converter import FontConverter from aspose_font import FontType from pathlib import Path woff = FontLoader.open("MyFont.woff") woff2 = FontConverter.convert(woff, FontType.WOFF2) Path("MyFont.woff2").write_bytes(woff2.to_bytes(FontType.WOFF2)) print("Upgraded WOFF 1 (zlib) -> WOFF2 (Brotli)") ``` --- ### Loading WOFF2 Fonts `FontLoader.open` decompresses the Brotli-compressed glyph data automatically: ```python from aspose_font.loader import FontLoader woff2 = FontLoader.open("MyFont.woff2") print(f"Name : {woff2.font_name}") print(f"Family : {woff2.font_family}") print(f"Glyphs : {woff2.num_glyphs}") print(f"Type : {woff2.font_type}") ``` No decompression step is required. The loader applies `BrotliDecoder` to the glyph stream before constructing the `Woff2Font` instance. --- ### Low-Level Brotli Encoding > **Internal API notice:** `BrotliEncoder` and `BrotliDecoder` are internal > utilities (`aspose_font._brotli`). They are not part of the public API surface > and may change between releases. For WOFF2 font compression, prefer > `FontLoader.open()` combined with `Woff2Font`, which handles Brotli > transparently. For compressing arbitrary binary data independently of font operations, the internal `BrotliEncoder` exposes a `quality` parameter (0-11): ```python from aspose_font._brotli import BrotliEncoder # internal API data = b"Sample data to compress" * 200 # quality=11 = maximum compression; quality=0 = fastest encoder = BrotliEncoder(quality=11) compressed = encoder.encode(data) ratio = len(compressed) / len(data) print(f"Original : {len(data)} bytes") print(f"Compressed : {len(compressed)} bytes") print(f"Ratio : {ratio:.2%}") ``` `BrotliEncoder.encode(data)` accepts `bytes` and returns `bytes`. The encoder instance is not reusable across calls with different quality settings — create a new instance for each quality level. --- ### Low-Level Brotli Decoding > **Internal API notice:** See the notice above — `BrotliDecoder` is also an > internal utility. `BrotliDecoder.decode` is a class-level method that decompresses any Brotli payload: ```python from aspose_font._brotli import BrotliEncoder, BrotliDecoder # internal API original = b"Round-trip compression test" * 100 # Compress encoder = BrotliEncoder(quality=6) compressed = encoder.encode(original) print(f"Compressed to {len(compressed)} bytes") # Decompress recovered = BrotliDecoder.decode(compressed) assert recovered == original print(f"Decompressed: {len(recovered)} bytes — data intact: {recovered == original}") ``` `BrotliDecoder.decode` takes a `bytes` payload and returns `bytes`. It processes the entire payload in one call — there is no streaming interface. --- ## Compression Level Guide The `quality` parameter in `BrotliEncoder.__init__` maps to the standard Brotli quality levels: | Quality | Speed | Compression Ratio | Typical Use | |---------|-------|-------------------|-------------| | 0 | Fastest | Lowest | Real-time / latency-sensitive | | 1-3 | Fast | Low | Streaming data | | 4-6 | Balanced | Medium | General-purpose (recommended) | | 7-9 | Slow | High | Static assets | | 10-11 | Slowest | Highest | Font files, archival | For font production (WOFF2), quality 11 gives the best file size and is used in the standard `FontConverter.convert` path. --- ## Quick Start Install the library: Convert a TTF to WOFF2 and verify the compression: ```python from aspose_font.loader import FontLoader from aspose_font.converter import FontConverter from aspose_font import FontType from pathlib import Path # Convert to WOFF2 (Brotli applied automatically) ttf = FontLoader.open("MyFont.ttf") woff2 = FontConverter.convert(ttf, FontType.WOFF2) woff2_bytes = woff2.to_bytes(FontType.WOFF2) # Compare sizes ttf_bytes = ttf.to_bytes(FontType.TTF) print(f"TTF : {len(ttf_bytes)} bytes") print(f"WOFF2 : {len(woff2_bytes)} bytes ({len(woff2_bytes)/len(ttf_bytes):.1%} of TTF)") Path("MyFont.woff2").write_bytes(woff2_bytes) print("Done — WOFF2 saved") ``` --- ## Open Source and Licensing Aspose.Font FOSS for Python is released under the MIT License. The bundled Brotli implementation is included in the package under its own open-source license. You can use the library in personal, commercial, and open-source projects at no cost. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [WOFF How-To Guide](https://kb.aspose.org/font/python/how-to-work-with-woff-python/) - [Brotli Compression How-To](https://kb.aspose.org/font/python/how-to-work-with-brotli-python/) - [API Reference](https://reference.aspose.org/font/python/) - [KB Articles](https://kb.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Working with EOT Fonts in Python using Aspose.Font FOSS URL: https://blog.aspose.org/font/python/eot-fonts-in-python/ Aspose.Font FOSS for Python provides a full Python API for loading, inspecting, and converting Embedded OpenType (EOT) font files. Access EotHeader metadata fields such as eot_size, version, flags, and charset, traverse the inner TtfFont, and serialize fonts back to EOT bytes using EotSerializer. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/eot-fonts-in-python/ --- # Working with EOT Fonts in Python using Aspose.Font FOSS ## Introduction Embedded OpenType (EOT) is a compact font format originally developed for embedding TrueType fonts in web pages. An EOT file wraps a TTF or OTF font with a fixed-size header containing metadata fields that describe font dimensions, version, charset, and embedding permissions. Although modern web development has largely moved to WOFF/WOFF2, EOT files remain in circulation in legacy documents and enterprise applications. Aspose.Font FOSS for Python provides direct access to EOT font internals through the `EotFont` class and its companion `EotHeader`. You can load an EOT file with `FontLoader.open`, read header fields, traverse the inner `TtfFont`, and serialize the result back to bytes or to a file using `Font.save`. The library is distributed as `aspose-font` and licensed under the MIT License. It has no mandatory commercial dependencies and works with the standard Python 3 runtime. --- ## Key Features ### Loading EOT Fonts Use `FontLoader.open` to load an EOT file from a path or a bytes object. The method returns an `EotFont` instance when it detects the EOT signature: ```python from aspose_font import FontLoader, EotFont font = FontLoader.open("fonts/sample.eot") assert isinstance(font, EotFont) print(font.font_name) # e.g. "Roboto" print(font.font_family) # e.g. "Roboto" print(font.num_glyphs) # number of glyphs in the inner font ``` `FontLoader.open` reads the file extension and header magic to detect the format automatically. No `font_type` argument is required for common font files. --- ### Reading EotHeader Metadata `EotFont` exposes the header fields directly as properties on the class. These correspond to the fields defined in the EOT binary specification: ```python from aspose_font import FontLoader, EotFont, EotSerializer # Load EOT — FontLoader returns an EotFont instance for .eot files loaded = FontLoader.open("fonts/sample.eot") # Serialize back to bytes to confirm the font loaded correctly eot_bytes = EotSerializer.serialize(loaded) print(f"EOT data loaded: {len(eot_bytes)} bytes") # Base Font properties work on any loaded font print("Font name:", loaded.font_name) print("Glyphs :", loaded.num_glyphs) ``` The `EotFont` class exposes the following header metadata as properties: - `eot_version` (`int`) — EOT format version (e.g. `0x00020002`) - `flags` (`int`) — embedding permission flags - `charset` (`int`) — character set identifier (0 = ANSI, 1 = DEFAULT) - `italic` (`int`) — italic flag (0 or 1) - `weight` (`int`) — font weight (e.g., 400 for Regular, 700 for Bold) - `fs_type` (`int`) — OS/2 fsType embedding bits Use `flags` and `fs_type` to determine whether the font permits subsetting or embedding, which is relevant when processing fonts for redistribution pipelines. ### Accessing the Inner TtfFont Every `EotFont` wraps a standard TrueType font. The `inner_font` property returns the `TtfFont` instance, giving you access to the full TrueType table set: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/sample.eot") # Metrics are accessible directly from the loaded font metrics = loaded.metrics print("Units per em :", metrics.units_per_em) print("Ascender :", metrics.ascender) print("Descender :", metrics.descender) print("Line gap :", metrics.line_gap) ``` The `inner_font` property on `EotFont` returns the wrapped `TtfFont` instance, providing access to the full TrueType table set, kern pairs, and encoding tables. --- ### Serializing EOT to Bytes `EotSerializer.serialize` converts any `Font` object to a raw EOT byte string: ```python from aspose_font import FontLoader, EotFont, EotSerializer font = FontLoader.open("fonts/sample.eot") assert isinstance(font, EotFont) eot_bytes = EotSerializer.serialize(font) with open("output/sample_copy.eot", "wb") as fh: fh.write(eot_bytes) print(f"Serialized {len(eot_bytes)} bytes") ``` --- ### Converting TTF to EOT `EotSerializer.serialize` accepts any `Font` instance, so you can load a TTF and serialize it directly to EOT bytes: ```python from aspose_font import FontLoader, EotFont, EotSerializer ttf = FontLoader.open("fonts/Roboto-Regular.ttf") eot_bytes = EotSerializer.serialize(ttf) with open("output/Roboto-Regular.eot", "wb") as fh: fh.write(eot_bytes) reloaded = FontLoader.open("output/Roboto-Regular.eot") assert isinstance(reloaded, EotFont) print("Converted and verified:", reloaded.font_name) ``` --- ### Font Metrics and Kern Pairs The `EotFont` inherits the full `Font` interface, so metrics and encoding are available directly without going through `inner_font`: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/sample.eot") metrics = loaded.metrics print(f"Ascender : {metrics.ascender}") print(f"Descender: {metrics.descender}") print(f"Line gap : {metrics.line_gap}") print(f"Underline: {metrics.underline_position}") for pair in loaded.get_kern_pairs(): print(f" Kern: {pair}") ``` --- ## Quick Start Install the library: Load and inspect an EOT font: ```python from aspose_font import FontLoader, EotFont, EotSerializer loaded = FontLoader.open("sample.eot") # Base font info print(f"Font name : {loaded.font_name}") print(f"Glyphs : {loaded.num_glyphs}") # Metrics metrics = loaded.metrics print(f"UPM : {metrics.units_per_em}") print(f"Ascender : {metrics.ascender}") # Serialize the loaded font back to EOT bytes eot_bytes = EotSerializer.serialize(loaded) print(f"Serialized: {len(eot_bytes)} bytes") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | TTF | .ttf | ✓ | — | | OTF | .otf | ✓ | — | | EOT | .eot | ✓ | — | | CFF | .cff | ✓ | — | | TYPE1 | .pfb/.pfa | ✓ | — | | WOFF | .woff | ✓ | — | | WOFF2 | .woff2 | ✓ | — | All formats listed above are supported for loading via `FontLoader.open`. Writing to a specific format uses `Font.save` or `EotSerializer.serialize` for EOT. --- ## Open Source & Licensing Aspose.Font FOSS for Python is released under the MIT License. You can use it in personal, commercial, and open-source projects at no cost. The source code is available on GitHub, packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Working with CFF Fonts in Python using Aspose.Font FOSS URL: https://blog.aspose.org/font/python/font-cff-in-python/ Deep dive into CFF font processing with Aspose.Font FOSS for Python: loading CFF fonts, reading charsets and encoding maps, parsing CFF dictionaries and indexes, and interpreting Type 2 charstring programs with the CffFont and related classes. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/font-cff-in-python/ --- # Working with CFF Fonts in Python using Aspose.Font FOSS ## Introduction Compact Font Format (CFF) is the binary glyph description format used inside OpenType fonts with a PostScript-compatible outline engine. Aspose.Font FOSS for Python exposes a dedicated set of classes under the `aspose_font.cff` namespace for reading and inspecting CFF data structures: `CffFont`, `CffCharset`, `CffEncoding`, `CffDict`, `CffIndex`, and `Type2Interpreter`. This post walks through how to load CFF fonts, navigate their internal tables, and interpret charstring programs using the library. The package is MIT licensed. Install it as follows: --- ## Key Features ### Loading a CFF Font `FontLoader.open()` detects CFF format automatically — pass either a standalone `.cff` file or an OTF file that embeds a CFF outline table. The returned object is a `CffFont` (accessible via the `cff_font` property on `TtfFont` for OTF files). ```python from aspose_font.loader import FontLoader # Load a standalone CFF file font = FontLoader.open("OpenSans.cff") # Load a standalone CFF file (auto-detected from format) font = FontLoader.open("OpenSans.cff") print(font.font_name, font.num_glyphs) ``` ### CFF Charset — Mapping Glyph IDs to Names `CffCharset` maps glyph IDs (GIDs) to PostScript glyph names. Use `standard()` to get the standard ISO Adobe charset or `from_reader()` to parse a charset from binary CFF data. The `name_for()` method returns the PostScript name for a GID, and `gid_for()` performs the reverse lookup. ```python from aspose_font.cff.charset import CffCharset charset = CffCharset.standard() print(charset.name_for(1)) # ".notdef" or similar print(charset.gid_for("A")) # GID for the PostScript name "A" ``` ### CFF Encoding — Unicode-to-GID Mapping `CffEncoding` handles the CFF encoding table, which maps character codes to glyph IDs. `standard()` returns the standard encoding, `expert()` returns the expert encoding, and `from_reader()` parses a custom encoding from CFF binary data. Use `unicode_to_gid()` to look up a GID by Unicode code point and `get_all_codepoints()` to enumerate all mapped code points. ```python from aspose_font.cff.encoding import CffEncoding encoding = CffEncoding.standard() gid = encoding.unicode_to_gid(0x41) # Unicode for 'A' all_codepoints = encoding.get_all_codepoints() print(f"Standard encoding covers {len(all_codepoints)} code points") ``` ### CFF Dictionary Parsing CFF fonts store top-level and private metadata in dictionaries. `CffDict.from_bytes()` parses a raw CFF DICT blob and gives you `get()` and `set()` access by operator key. `TopDict.from_dict()` specialises this for top-level CFF dictionaries, and `PrivateDict.from_dict()` does the same for private DICTs. ```python from aspose_font.cff.dict_ import CffDict # Parse a raw CFF DICT from bytes raw_dict_bytes = b"..." # CFF-encoded DICT bytes d = CffDict.from_bytes(raw_dict_bytes) vals = d.get(21) # retrieve values for operator 21 (PostScript CharstringType) ``` ### CFF Index Structures `CffIndex` represents a CFF INDEX data structure — a length-prefixed array of variable- length byte strings used for charstrings, subrs, and name tables. `from_reader()` parses an INDEX from a binary reader and the result is subscriptable by integer index. ```python from aspose_font.cff.index import CffIndex from aspose_font._io import BinaryReader # internal API — may change between releases import io raw_index = b"..." # raw CFF INDEX bytes reader = BinaryReader(io.BytesIO(raw_index)) index = CffIndex.from_reader(reader) print(f"INDEX entries: {len(index)}") ``` ### Type 2 Charstring Interpretation `Type2Interpreter` executes a Type 2 charstring program (the compact PostScript-like format used in CFF fonts) and produces a `GlyphPath` of outline commands. Call `interpret()` with the charstring bytes and the associated private dictionary. This enables you to extract raw glyph outlines from CFF charstrings without a full PostScript interpreter. ```python from aspose_font.cff.type2 import Type2Interpreter interpreter = Type2Interpreter() glyph_path = interpreter.interpret(charstring_bytes, private_dict) for cmd in glyph_path.commands: print(type(cmd).__name__, cmd) ``` --- ## Quick Start ```python from aspose_font.loader import FontLoader # Load an OTF with embedded CFF outlines font = FontLoader.open("OpenSans-Regular.otf") glyph_id = font.encoding.unicode_to_gid(0x41) glyph = font.glyph_accessor.get_glyph_by_id(glyph_id) print(f"Path commands for 'A': {len(glyph.path.commands)}") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | CFF | .cff | ✓ | ✓ | | OTF | .otf | ✓ | ✓ | | TTF | .ttf | ✓ | ✓ | | WOFF | .woff | ✓ | ✓ | | WOFF2 | .woff2 | ✓ | ✓ | | EOT | .eot | ✓ | ✓ | | TYPE1 | .pfb / .pfa | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Font FOSS for Python is MIT licensed. Source code is on GitHub at [aspose-font-foss/Aspose.Font-FOSS-for-Python](https://github.com/aspose-font-foss/Aspose.Font-FOSS-for-Python). Packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Core Font Management in Python with Aspose.Font FOSS URL: https://blog.aspose.org/font/python/font-core-management-python/ Learn how to use Aspose.Font FOSS for Python to load fonts, inspect glyph encoding maps, access font metrics, perform format conversion with FontConverter, and clean fonts for web deployment with FontCleaner — all without OS font dependencies. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/font-core-management-python/ --- # Core Font Management in Python with Aspose.Font FOSS ## Introduction Aspose.Font FOSS for Python provides a coherent set of classes for every common font management task: loading font files in multiple formats, reading metadata and glyph data, converting between formats, subsetting for web delivery, and cleaning binary tables for optimal file size. This guide walks through each core capability with working code examples drawn from the library's verified API. The package (`aspose-font`) is MIT licensed, requires Python 3.10+, and has no OS-level font library dependencies. Install it as follows: --- ## Key Features ### Loading Fonts with FontLoader `FontLoader` is the single entry point for all font loading operations. The static `open()` method accepts a file path (str or Path) and auto-detects the format. The `load()` method accepts raw bytes for in-memory workflows. Both return a `Font`-typed object you can inspect immediately. ```python from aspose_font.loader import FontLoader # Load from file path — format detected automatically font = FontLoader.open("Roboto-Regular.ttf") # Load from raw bytes (e.g., from a network request or database blob) with open("OpenSans-Regular.otf", "rb") as f: font_bytes = f.read() font = FontLoader.load(font_bytes) ``` ### Reading Font Metadata via the Font Base Class Once loaded, the `Font` base class exposes standard metadata properties without requiring you to parse binary font tables. The properties `font_name`, `font_family`, `font_style`, and `num_glyphs` cover the most common metadata needs. ```python from aspose_font.loader import FontLoader font = FontLoader.open("NotoSans-Regular.ttf") print(f"Name: {font.font_name}") print(f"Family: {font.font_family}") print(f"Style: {font.font_style}") print(f"Glyphs: {font.num_glyphs}") ``` ### Glyph Encoding and Access `FontEncoding` maps Unicode code points to glyph IDs. Use `unicode_to_gid()` for single code points or `get_all_codepoints()` to enumerate the full coverage of the font. `GlyphAccessor` then retrieves glyph objects by ID via `get_glyph_by_id()`, by Unicode via `get_glyph_by_unicode()`, or for a text string via `get_glyphs_for_text()`. ```python from aspose_font.loader import FontLoader font = FontLoader.open("OpenSans-Regular.otf") # Map Unicode code point to glyph ID glyph_id = font.encoding.unicode_to_gid(0x41) # 'A' print(f"Glyph ID for 'A': {glyph_id}") # Retrieve glyph object glyph = font.glyph_accessor.get_glyph_by_id(glyph_id) # Inspect path commands for cmd in glyph.path.commands: print(type(cmd).__name__, cmd) ``` ### Font Conversion with FontConverter `FontConverter.convert()` converts a loaded font between supported formats. Pass the source font and the target format identifier to get a new font object in the target format. The method handles CFF, TTF, WOFF, WOFF2, EOT, and Type 1 as both source and target. ```python from aspose_font.loader import FontLoader from aspose_font.converter import FontConverter source = FontLoader.open("MyFont.ttf") converted = FontConverter.convert(source, target_format="woff2") ``` ### Web Optimization with FontCleaner `FontCleaner.clean_for_web()` removes binary tables that are unnecessary for web font delivery — specifically DSIG, FFTM, and meta — and strips Mac platform (platform_id=1) name records from the name table. The result is a leaner binary that reduces network payload without touching outlines or metrics. Optional keyword arguments let you preserve specific table types if needed. ```python from aspose_font.loader import FontLoader from aspose_font.cleaner import FontCleaner font = FontLoader.open("Roboto-Regular.ttf") # Strip all legacy tables and Mac name records (default) cleaned = FontCleaner.clean_for_web(font) # Preserve specific metadata tables if required cleaned_selective = FontCleaner.clean_for_web( font, drop_metadata_tables=False, drop_legacy_tables=True, drop_mac_names=True, ) ``` ### Glyph Path Inspection Every `Glyph` object exposes its outline as a `GlyphPath` whose `commands` sequence contains typed instances of `MoveTo`, `LineTo`, `QuadraticTo`, `CurveTo`, and `ClosePath`. Each command carries the relevant coordinate attributes — for example, `CurveTo` has `x1`, `y1`, `x2`, `y2`, `x`, `y` — allowing you to extract raw Bézier data for rendering, SVG generation, or collision geometry. ```python from aspose_font.loader import FontLoader from aspose_font import CurveTo, LineTo font = FontLoader.open("OpenSans-Regular.otf") glyph_id = font.encoding.unicode_to_gid(ord("A")) glyph = font.glyph_accessor.get_glyph_by_id(glyph_id) curves = [cmd for cmd in glyph.path.commands if isinstance(cmd, CurveTo)] print(f"Cubic Bezier segments in 'A': {len(curves)}") ``` --- ## Quick Start ```python from aspose_font.loader import FontLoader from aspose_font.cleaner import FontCleaner # Load, inspect, and clean a font in five lines font = FontLoader.open("MyFont.ttf") print(font.font_family, font.num_glyphs, "glyphs") cleaned = FontCleaner.clean_for_web(font) print("Font cleaned for web delivery") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | TTF | .ttf | ✓ | ✓ | | OTF | .otf | ✓ | ✓ | | CFF | .cff | ✓ | ✓ | | TYPE1 | .pfb / .pfa | ✓ | ✓ | | WOFF | .woff | ✓ | ✓ | | WOFF2 | .woff2 | ✓ | ✓ | | EOT | .eot | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Font FOSS for Python is MIT licensed. The source is on GitHub at [aspose-font-foss/Aspose.Font-FOSS-for-Python](https://github.com/aspose-font-foss/Aspose.Font-FOSS-for-Python), packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Working with Font Tables in Python URL: https://blog.aspose.org/font/python/font-tables-in-python/ Learn how to read, inspect, and modify OpenType and TrueType font tables using Aspose.Font FOSS for Python. Access head, name, cmap, OS/2, kern, and glyf tables through the TtfTableSet API. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/font-tables-in-python/ --- # Working with Font Tables in Python ## Introduction Font files are structured around tables — each table stores a specific category of data such as glyph outlines, character mappings, naming metadata, or horizontal metrics. Understanding and accessing these tables is essential for tasks like font analysis, metadata editing, quality assurance, and format conversion. Aspose.Font FOSS for Python (`aspose-font`) gives you direct access to the full set of OpenType and TrueType tables through a clean Python API. The library is released under the MIT license with zero external dependencies, so you can integrate it into any project without licensing concerns. This post walks through the key table classes available in the library — from reading header metadata to inspecting glyph data and modifying name records — all backed by the `TtfTableSet` container on `TtfFont`. --- ## Key Features ### Loading a Font and Accessing Tables Every font loaded with `FontLoader` exposes its parsed tables through the `ttf_tables` property on `TtfFont`. The `TtfTableSet` object provides typed access to each standard table, plus raw bytes access via `get_raw()` for custom or unrecognized tables. ```python import aspose_font font = aspose_font.FontLoader.open("MyFont.ttf") tables = font.ttf_tables # Typed table access head = tables.head name = tables.name cmap = tables.cmap # Raw bytes for any table tag raw_os2 = tables.get_raw("OS/2") ``` ### Reading the Head Table The `HeadTable` stores fundamental font-wide parameters: units per em, revision, bounding box, creation date, and style flags. These values are critical for rendering engines and font validators. ```python import aspose_font font = aspose_font.FontLoader.open("MyFont.ttf") head = font.ttf_tables.head print(f"Units per em: {head.units_per_em}") print(f"Revision: {head.font_revision}") print(f"Bounding box: ({head.x_min}, {head.y_min}) to ({head.x_max}, {head.y_max})") print(f"Mac style flags: {head.mac_style}") print(f"Glyph data format: {head.glyph_data_format}") ``` ### Working with the Name Table The `NameTable` holds all human-readable metadata: font family name, style, copyright, license, designer, and description. You can query records by name ID, retrieve localized names, or modify entries for rebranding. ```python import aspose_font font = aspose_font.FontLoader.open("MyFont.ttf") name_table = font.ttf_tables.name # Read the font family name (name ID 1) family = name_table.best_name(1, ["en"]) print(f"Family: {family}") # List all localized versions of the full name (name ID 4) localized = name_table.localized_names(4) for lang, value in localized.items(): print(f" {lang}: {value}") # Replace the font family name name_table.replace_name(1, "MyCustomFamily") ``` ### Inspecting the CMap Table The `CmapTable` maps Unicode codepoints to glyph IDs. It may contain multiple subtables for different platform and encoding combinations. Use `best_subtable()` to get the most suitable mapping for your use case. ```python import aspose_font font = aspose_font.FontLoader.open("MyFont.ttf") cmap = font.ttf_tables.cmap # Get the best Unicode subtable subtable = cmap.best_subtable() print(f"Platform: {subtable.platform_id}, Encoding: {subtable.encoding_id}") # Look up the glyph ID for 'A' gid = subtable.get_gid(ord("A")) print(f"Glyph ID for 'A': {gid}") ``` ### Reading OS/2 and Horizontal Metrics The `Os2Table` provides OS/2 and Windows-specific metrics including typographic ascender/descender, embedding flags, and Panose classification. The `HheaTable` and `HmtxTable` supply horizontal layout metrics used for text shaping. ```python import aspose_font font = aspose_font.FontLoader.open("MyFont.ttf") os2 = font.ttf_tables.os2 hhea = font.ttf_tables.hhea print(f"Typo ascender: {os2.s_typo_ascender}") print(f"Typo descender: {os2.s_typo_descender}") print(f"Embedding flags (fsType): {os2.fs_type}") print(f"Panose: {os2.panose.hex()}") print(f"Hhea ascender: {hhea.ascender}") print(f"Max advance width: {hhea.advance_width_max}") print(f"Number of hmetrics: {hhea.number_of_hmetrics}") ``` ### Kerning and Glyph Data The `KernTable` stores kerning pairs for horizontal spacing adjustments. The `GlyfTable` contains the actual glyph outline data for TrueType fonts. You can also use `PostTable` to resolve glyph names. ```python import aspose_font font = aspose_font.FontLoader.open("MyFont.ttf") # Kerning lookup kern = font.ttf_tables.kern if kern: pairs = kern.pairs print(f"Total kern pairs: {len(pairs)}") # Look up a specific pair by glyph IDs adjustment = kern.get(36, 57) print(f"Kern adjustment: {adjustment}") # Glyph name from post table post = font.ttf_tables.post if post: glyph_name = post.glyph_name(0) print(f"Glyph 0 name: {glyph_name}") ``` --- ## Quick Start ```python import aspose_font # Load any TTF or OTF font font = aspose_font.FontLoader.open("MyFont.ttf") tables = font.ttf_tables # Print basic table info print(f"Font: {font.font_name}") print(f"Family: {font.font_family}") print(f"Glyphs: {font.num_glyphs}") print(f"Units/em: {tables.head.units_per_em}") # Read name table entries name_table = tables.name for name_id in [0, 1, 2, 4, 5, 6]: value = name_table.best_name(name_id, ["en"]) if value: print(f" Name ID {name_id}: {value}") # Check character coverage cmap = tables.cmap subtable = cmap.best_subtable() for char in "ABCabc012": gid = subtable.get_gid(ord(char)) print(f" '{char}' -> glyph {gid}") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | TTF | .ttf | ✓ | ✓ | | OTF | .otf | ✓ | ✓ | | CFF | .cff | ✓ | ✓ | | WOFF | .woff | ✓ | ✓ | | WOFF2 | .woff2 | ✓ | ✓ | | EOT | .eot | ✓ | — | | TYPE1 | .pfb/.pfa | ✓ | — | --- ## Open Source & Licensing Aspose.Font FOSS for Python is released under the MIT license. The source code is available on GitHub, packaged as `aspose-font`. You are free to use, modify, and distribute it in both personal and commercial projects without restriction. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Font FOSS for Python URL: https://blog.aspose.org/font/python/python-font-ttf-woff-library/ Aspose.Font FOSS for Python is a pure-Python, MIT-licensed library for loading, inspecting, converting, subsetting, and previewing fonts across TTF, OTF, CFF, Type 1, WOFF, WOFF2, and EOT formats without any OS-level font dependencies. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/python-font-ttf-woff-library/ --- # Introducing Aspose.Font FOSS for Python ## Introduction Aspose.Font FOSS for Python is a new open-source library that gives Python developers a complete toolkit for working with font files programmatically. Whether you need to load a TTF for glyph inspection, convert an OTF to WOFF2 for web delivery, subset a font to reduce payload size, or generate animated previews of variable font axes, the library exposes a unified, dependency-free API for all these tasks. The library is distributed as `aspose-font` under the MIT license. It requires Python 3.10 or later and has no dependency on OS-level font rendering libraries such as FreeType or HarfBuzz. This makes it well-suited for headless server environments, CI pipelines, and containerized workloads where installing system fonts is impractical. Aspose.Font FOSS v1.0.0 supports loading fonts in TTF, OTF, CFF, Type 1, WOFF, WOFF2, and EOT formats, with export capability to the same set of formats via `FontConverter`. --- ## What's Included ### Font Loading and Metadata Access The `FontLoader` class is the single entry point for loading fonts. Call `FontLoader.open()` with a file path or raw bytes and the library will detect the format automatically and return the appropriate font object. Once loaded, the `Font` base class gives you access to `font_name`, `font_family`, `font_style`, `num_glyphs`, and the encoding map. ```python from aspose_font.loader import FontLoader font = FontLoader.open("Roboto-Regular.ttf") print(font.font_name) # "Roboto" print(font.font_family) # "Roboto" print(font.num_glyphs) # number of glyphs in the font ``` ### Glyph Inspection and Path Access The `GlyphAccessor` class lets you look up glyphs by glyph ID or Unicode code point via `get_glyph_by_id()` and `get_glyph_by_unicode()`. To resolve all glyphs for a string of text at once, use `get_glyphs_for_text()`. Each `Glyph` object exposes its outline path as a sequence of typed path commands — `MoveTo`, `LineTo`, `QuadraticTo`, `CurveTo`, and `ClosePath` — giving you access to raw Bézier data without a rendering engine. ```python from aspose_font.loader import FontLoader font = FontLoader.open("OpenSans-Regular.otf") glyph_id = font.encoding.unicode_to_gid(0x41) # Unicode code point for 'A' glyph = font.glyph_accessor.get_glyph_by_id(glyph_id) for cmd in glyph.path.commands: print(type(cmd).__name__, cmd) ``` ### Font Subsetting `FontSubsetter` provides multiple subsetting strategies. Use `subset_by_text()` to keep only the glyphs needed for a specific string, `subset_by_gids()` to specify glyph IDs directly, or `subset_for_web()` to apply a web-optimized preset that drops rarely used glyphs and tables. The `analyze_coverage()` method lets you inspect what percentage of the original font a subset covers before committing to it. ```python from aspose_font.loader import FontLoader from aspose_font.subsetter import FontSubsetter font = FontLoader.open("NotoSans-Regular.ttf") # Subset to the characters needed for a Latin-script page result = FontSubsetter.subset_by_text(font, "Hello, World!") ``` ### Web Font Optimization `FontCleaner.clean_for_web()` strips DSIG, FFTM, and meta tables and removes Mac platform name records from the font's name table. The result is a smaller binary that loads faster as a web font without changing the glyph outlines or metrics. ```python from aspose_font.loader import FontLoader from aspose_font.cleaner import FontCleaner font = FontLoader.open("Roboto-Regular.ttf") cleaned = FontCleaner.clean_for_web(font) # stripped of legacy tables; ready for WOFF2 packaging ``` ### Variable Font Animation Previews For variable fonts, `AnimationPreviewBuilder` can generate an animated APNG that sweeps one axis from a start value to an end value. The `build_axis_sweep()` method accepts the axis tag (e.g., `"wdth"` or `"wght"`), a frame count, frames per second, and an optional bounce flag that reverses the sweep to create a looping animation. The result is an `AnimationAsset` whose `write_to()` method saves the APNG to disk. ```python from aspose_font.loader import FontLoader from aspose_font.animation import AnimationPreviewBuilder font = FontLoader.open("Roboto-VariableFont_wdth,wght.ttf") asset = AnimationPreviewBuilder.build_axis_sweep( font, axis_tag="wdth", start_val=75.0, end_val=100.0, frames=3, fps=10, text="A", size=10.0, bounce=True, ) asset.write_to("roboto-sweep-wdth.png") ``` --- ## Quick Start Install the library with the command below: Then load a font and inspect its metadata in a few lines: ```python from aspose_font.loader import FontLoader font = FontLoader.open("MyFont.ttf") print(f"Family: {font.font_family}") print(f"Style: {font.font_style}") print(f"Glyphs: {font.num_glyphs}") # Look up a glyph by Unicode code point glyph_id = font.encoding.unicode_to_gid(ord("A")) glyph = font.glyph_accessor.get_glyph_by_id(glyph_id) print(f"Path commands for 'A': {len(glyph.path.commands)}") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | TTF | .ttf | ✓ | ✓ | | OTF | .otf | ✓ | ✓ | | CFF | .cff | ✓ | ✓ | | TYPE1 | .pfb / .pfa | ✓ | ✓ | | WOFF | .woff | ✓ | ✓ | | WOFF2 | .woff2 | ✓ | ✓ | | EOT | .eot | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Font FOSS for Python is published under the MIT license. You can use it in commercial projects, modify it, and distribute it freely. The source code is available on GitHub at [aspose-font-foss/Aspose.Font-FOSS-for-Python](https://github.com/aspose-font-foss/Aspose.Font-FOSS-for-Python), packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Working with TrueType Fonts in Python using Aspose.Font FOSS URL: https://blog.aspose.org/font/python/ttf-fonts-in-python/ Aspose.Font FOSS for Python provides a full Python API for loading, inspecting, and converting TrueType (TTF) and OpenType fonts. Access raw OpenType table bytes via TtfTableSet, enumerate kern pairs, and work with variable font axes and named instances using TtfFont. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/ttf-fonts-in-python/ --- # Working with TrueType Fonts in Python using Aspose.Font FOSS ## Introduction TrueType fonts (`.ttf`) and their OpenType superset (`.otf`) are the dominant font formats on modern operating systems. Both formats share the same binary table structure rooted in the OpenType specification. Aspose.Font FOSS for Python exposes this structure through `TtfFont`, giving direct access to individual OpenType tables, kern pair data, variable font axes, and glyph outlines. The `TtfFont` class extends the `Font` base class with TTF-specific methods including `get_blob`, `get_table_bytes`, `set_table_bytes`, and `instantiate` for variable font axis locking. The `TtfTableSet` property (`ttf_tables`) provides typed access to the most common OpenType tables: `head`, `hhea`, `maxp`, `os2`, `name`, `post`. The library is distributed as `aspose-font` and licensed under the MIT License. It has no mandatory commercial dependencies. --- ## Key Features ### Loading TTF and OTF Fonts Use `FontLoader.open` to load any TrueType or OpenType font file: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/Roboto-Regular.ttf") print(loaded.font_name) print(loaded.font_family) print(loaded.font_style) print(loaded.num_glyphs) ``` `FontLoader.open` detects the font format from the file header. Both `.ttf` (TrueType) and `.otf` (OpenType CFF) files are supported and both return a `TtfFont` instance. --- ### Accessing OpenType Tables via TtfTableSet The `ttf_tables` property returns a `TtfTableSet` with typed accessors for common OpenType tables. Each property returns the table object or `None` if absent: The `ttf_tables` property on `TtfFont` returns a `TtfTableSet` instance. Available table accessors: - `head` — `HeadTable | None` - `hhea` — `HheaTable | None` - `maxp` — `MaxpTable | None` - `os2` — `Os2Table | None` - `name` — `NameTable | None` - `post` — `PostTable | None` Each property returns the table object or `None` if that table is not present in the font file. Access `TtfTableSet` properties to check for specific tables before reading them. For tables not covered by named accessors, use `TtfTableSet.get_raw(tag)` to retrieve raw bytes by four-character OpenType tag. --- ### Reading Raw Table Bytes `get_table_bytes(tag)` returns the raw bytes for any OpenType table. Use `get_blob(tag)` for a None-safe variant that returns `None` when the table is absent: `TtfFont` provides two methods for raw table access: - `get_table_bytes(tag) -> bytes` — returns the raw bytes for a named table (raises if absent) - `get_blob(tag) -> bytes | None` — returns `None` if the table is absent (safe variant) Both methods accept a four-character OpenType table tag such as `"cmap"`, `"GDEF"`, or `"GPOS"`. Use `get_blob` when a table is optional so you can check for `None` before processing. --- ### Kern Pairs `get_kern_pairs()` returns all kern pairs encoded in the font. Each `KernPair` has `left` (GlyphId), `right` (GlyphId), and `value` (int in font units): ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/Roboto-Regular.ttf") pairs = loaded.get_kern_pairs() print(f"Kern pairs: {len(pairs)}") for pair in pairs[:5]: print(f" Left: {pair.left} Right: {pair.right} Value: {pair.value}") ``` --- ### Font Metrics Standard metrics are accessible through the `metrics` property: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/Roboto-Regular.ttf") metrics = loaded.metrics print(f"Units per em : {metrics.units_per_em}") print(f"Ascender : {metrics.ascender}") print(f"Descender : {metrics.descender}") print(f"Line gap : {metrics.line_gap}") print(f"Underline pos : {metrics.underline_position}") ``` --- ### Variable Font Support For variable fonts, `TtfFont` exposes `is_variable`, `variable_axes`, and `named_instances`. Use `get_axis(tag)` to retrieve a specific axis by its four-letter tag: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/RobotoFlex.ttf") print(f"Is variable: {loaded.is_variable}") print(f"Axes : {len(loaded.variable_axes)}") ``` The `get_axis(tag)` method on `TtfFont` retrieves a `VariableAxis` by its four-letter tag (e.g. `"wght"` for weight, `"wdth"` for width). It returns `None` if the axis is not present in the font's `fvar` table. --- ### Converting Fonts `to_bytes(font_type)` converts the font to a different format. Use the `FontType` enum to specify the target: ```python from aspose_font import FontLoader, FontType loaded = FontLoader.open("fonts/Roboto-Regular.ttf") ttf_bytes = loaded.to_bytes(FontType.TTF) with open("output/Roboto-copy.ttf", "wb") as fh: fh.write(ttf_bytes) print(f"Serialized: {len(ttf_bytes)} bytes") ``` --- ## Quick Start Install the library: Load a TTF font and inspect it: ```python from aspose_font import FontLoader, FontType loaded = FontLoader.open("Roboto-Regular.ttf") print(f"Font name : {loaded.font_name}") print(f"Family : {loaded.font_family}") print(f"Glyphs : {loaded.num_glyphs}") print(f"Variable : {loaded.is_variable}") metrics = loaded.metrics print(f"UPM : {metrics.units_per_em}") ttf_bytes = loaded.to_bytes(FontType.TTF) print(f"Serialized: {len(ttf_bytes)} bytes") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | TTF | .ttf | ✓ | — | | OTF | .otf | ✓ | — | | EOT | .eot | ✓ | — | | CFF | .cff | ✓ | — | | TYPE1 | .pfb/.pfa | ✓ | — | | WOFF | .woff | ✓ | — | | WOFF2 | .woff2 | ✓ | — | All formats load via `FontLoader.open`. TTF/OTF fonts return a `TtfFont` instance. --- ## Open Source & Licensing Aspose.Font FOSS for Python is released under the MIT License. You can use it in personal, commercial, and open-source projects at no cost. The source code is available on GitHub, packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Working with Type 1 Fonts in Python using Aspose.Font FOSS URL: https://blog.aspose.org/font/python/type1-fonts-in-python/ Aspose.Font FOSS for Python includes a complete API for loading, inspecting, and serializing Type 1 fonts. Access font metadata through Type1Font and Type1FontData, interpret charstrings with Type1Interpreter, and serialize fonts to PFB or PFA format using Type1Serializer. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/type1-fonts-in-python/ --- # Working with Type 1 Fonts in Python using Aspose.Font FOSS ## Introduction Type 1 is Adobe's original scalable font format, predating TrueType and OpenType. Type 1 fonts consist of two files: a `.pfb` (Printer Font Binary) file containing the encrypted font program, and an `.afm` (Adobe Font Metrics) file with kerning and metrics data. Despite being superseded by OpenType, Type 1 fonts remain prevalent in publishing workflows, PostScript pipelines, and archival documents. Aspose.Font FOSS for Python provides direct access to Type 1 internals through `Type1Font`, `Type1FontData`, `Type1Serializer`, and `Type1Interpreter`. You can load PFB or PFA files via `FontLoader.open`, inspect the embedded font program metadata, interpret charstrings to glyph paths, and serialize fonts back to PFB or PFA format. The library is distributed as `aspose-font` and licensed under the MIT License. It has no mandatory commercial dependencies and runs on standard Python 3. --- ## Key Features ### Loading Type 1 Fonts Use `FontLoader.open` to load a PFB or PFA file. The returned object exposes both the standard `Font` interface and Type 1-specific functionality through the `Type1Font` class: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/Courier.pfb") print(loaded.font_name) # e.g. "Courier" print(loaded.font_family) # e.g. "Courier" print(loaded.num_glyphs) # number of defined glyphs print(loaded.font_style) # style string, e.g. "Regular" ``` `FontLoader.open` detects the Type 1 format automatically from the file header. PFB and PFA files are both supported. --- ### Loading AFM Metrics Type 1 fonts ship their metrics in a separate `.afm` file. The `Type1Font` class exposes a `load_afm(path)` method that attaches the AFM data to the loaded font object, enabling kern pair lookups via `get_kern_pairs()`. Without the AFM file, `get_kern_pairs()` returns an empty list because kern data lives in the AFM file, not in the PFB program itself. The `load_afm` method accepts a file path string pointing to the companion `.afm` file. --- ### Accessing Type1FontData Metadata The `Type1FontData` class exposes the font program dictionary embedded in the Type 1 file. It includes metrics, bounding box, encoding vector, charstrings, and subroutines: ```python from aspose_font.type1.data import Type1FontData # Type1FontData is the font program dictionary parsed from the PFB # Access its properties to inspect the raw PostScript font data ``` `Type1FontData` properties: - `font_name` (`str`) — PostScript name of the font - `full_name` (`str`) — full human-readable name - `family_name` (`str`) — font family - `weight` (`str`) — weight string (e.g. `"Medium"`) - `italic_angle` (`float`) — italic angle in degrees - `is_fixed_pitch` (`bool`) — true for monospace fonts - `font_bbox` (`tuple[int, int, int, int]`) — bounding box `(llx, lly, urx, ury)` - `underline_position` (`int`) — underline position in font units - `underline_thickness` (`int`) — underline stroke thickness - `encoding` (`list[str]`) — 256-slot encoding vector (PostScript glyph names) - `charstrings` (`dict[str, bytes]`) — glyph name → charstring bytes mapping - `subrs` (`list[bytes]`) — subroutine byte strings used by the charstring engine - `len_iv` (`int`) — lenIV encryption parameter --- ### Interpreting Charstrings `Type1Interpreter` decodes Type 1 charstring programs into `GlyphPath` outlines. Pass the raw charstring bytes from `Type1FontData.charstrings` to `interpret`: ```python from aspose_font.type1.interpreter import Type1Interpreter interpreter = Type1Interpreter() charstring = b"\x0e" # seac or other charstring bytes glyph_path, stack_depth = interpreter.interpret(charstring) for cmd in glyph_path.commands: print(cmd) ``` `interpret` returns a `(GlyphPath, int)` tuple. The `GlyphPath` contains the drawing commands for the glyph outline. The integer is the final stack depth after execution, which is useful for debugging malformed charstrings. --- ### Serializing to PFB and PFA `Type1Serializer` converts a loaded Type 1 font back to binary PFB or text PFA format. Both methods accept any `Font` instance and return raw bytes: ```python from aspose_font import FontLoader from aspose_font.type1.serializer import Type1Serializer loaded = FontLoader.open("fonts/Courier.pfb") # Serialize to PFB (binary) format pfb_bytes = Type1Serializer.serialize_pfb(loaded) with open("output/Courier_copy.pfb", "wb") as fh: fh.write(pfb_bytes) # Serialize to PFA (text) format pfa_bytes = Type1Serializer.serialize_pfa(loaded) with open("output/Courier_copy.pfa", "wb") as fh: fh.write(pfa_bytes) print(f"PFB: {len(pfb_bytes)} bytes") print(f"PFA: {len(pfa_bytes)} bytes") ``` --- ### Font Metrics Metrics and encoding are accessible through the standard `Font` interface: ```python from aspose_font import FontLoader loaded = FontLoader.open("fonts/Courier.pfb") metrics = loaded.metrics print(f"Units per em : {metrics.units_per_em}") print(f"Ascender : {metrics.ascender}") print(f"Descender : {metrics.descender}") print(f"Underline pos : {metrics.underline_position}") print(f"Underline tck : {metrics.underline_thickness}") ``` --- ## Quick Start Install the library: Load a PFB font and inspect it: ```python from aspose_font import FontLoader from aspose_font.type1.serializer import Type1Serializer loaded = FontLoader.open("Courier.pfb") print(f"Font name : {loaded.font_name}") print(f"Family : {loaded.font_family}") print(f"Style : {loaded.font_style}") print(f"Glyphs : {loaded.num_glyphs}") metrics = loaded.metrics print(f"UPM : {metrics.units_per_em}") # Round-trip: serialize back to PFB pfb_bytes = Type1Serializer.serialize_pfb(loaded) print(f"Serialized: {len(pfb_bytes)} bytes") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | TTF | .ttf | ✓ | — | | OTF | .otf | ✓ | — | | EOT | .eot | ✓ | — | | CFF | .cff | ✓ | — | | TYPE1 | .pfb/.pfa | ✓ | — | | WOFF | .woff | ✓ | — | | WOFF2 | .woff2 | ✓ | — | Type 1 fonts are loaded via `FontLoader.open` and serialized via `Type1Serializer`. --- ## Open Source & Licensing Aspose.Font FOSS for Python is released under the MIT License. You can use it in personal, commercial, and open-source projects at no cost. The source code is available on GitHub, packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Working with WOFF and WOFF2 Web Fonts in Python using Aspose.Font FOSS URL: https://blog.aspose.org/font/python/woff-fonts-in-python/ Aspose.Font FOSS for Python provides a Python API for loading, inspecting, and converting WOFF and WOFF2 web fonts. Access XML metadata, inner TTF tables, kern pairs, and build complete web font packages using WoffFont, Woff2Font, and WebFontBuilder. --- Product: Aspose.Font Platform: python Page Type: index Canonical URL: https://blog.aspose.org/font/python/woff-fonts-in-python/ --- # Working with WOFF and WOFF2 Web Fonts in Python using Aspose.Font FOSS ## Introduction WOFF (Web Open Font Format) is the standard container for delivering fonts on the web. WOFF 1 wraps a TrueType or CFF font with zlib compression; WOFF 2 applies Brotli compression instead, typically achieving 20-30% better compression ratios. Both formats are supported by every modern browser and remain the recommended delivery format for web typography. Aspose.Font FOSS for Python now exposes WOFF and WOFF2 through the unified **`Font`** class. The class provides the same set of properties (`font_name`, `font_family`, `num_glyphs`), an optional `metadata_xml` block, an `inner_font` accessor that returns the underlying `TtfFont`, and a `to_bytes()` method for format conversion. The library is distributed as `aspose-font` and licensed under the MIT License with no mandatory commercial dependencies. --- ## Key Features ### Loading WOFF and WOFF2 Fonts Use `FontLoader.open` to load a WOFF or WOFF2 file. The loader detects the format from the file’s magic bytes automatically: ```python from aspose_font import FontLoader # Load WOFF 1 woff = FontLoader.open("MyFont.woff") print(f"Name : {woff.font_name}") print(f"Family : {woff.font_family}") print(f"Style : {woff.font_style}") print(f"Glyphs : {woff.num_glyphs}") print(f"Type : {woff.font_type}") # Load WOFF 2 woff2 = FontLoader.open("MyFont.woff2") print(f"Name : {woff2.font_name}") print(f"Glyphs : {woff2.num_glyphs}") ``` `FontLoader.open` returns a `WoffFont` for `.woff` files and a `Woff2Font` for `.woff2` files. Both classes implement the same `Font` base interface so code that reads properties is identical for both formats. --- ### Inspecting WOFF Metadata WOFF files may include an optional XML metadata block containing licensing information, credits, and a font description. Access it through the `metadata_xml` property: ```python from aspose_font.loader import FontLoader font = FontLoader.open("MyFont.woff") xml = getattr(font, "metadata_xml", None) if xml: print("WOFF metadata XML:") print(xml[:500]) else: print("No metadata block in this WOFF file") ``` The `metadata_xml` property returns a `str` with the raw XML, or `None` if the font does not contain a metadata block. Both `WoffFont` and `Woff2Font` expose this property. --- ### Accessing Inner TTF Tables WOFF and WOFF2 wrap a TrueType font. The `inner_font` property provides the underlying `TtfFont` with full access to its OpenType table set: ```python from aspose_font.loader import FontLoader font = FontLoader.open("MyFont.woff") inner = getattr(font, "inner_font") tables = inner.ttf_tables # TtfTableSet print(f"Units/em : {tables.head.units_per_em}") print(f"Ascender : {tables.hhea.ascender}") print(f"Num glyphs : {tables.maxp.num_glyphs}") print(f"Family name : {tables.name.best_name(1)}") ``` Through `inner.ttf_tables` you can access all standard OpenType tables: `head`, `hhea`, `maxp`, `os2`, `name`, and `post`. For tables without a named accessor, use `inner.get_blob(tag)` to retrieve raw bytes by OpenType tag. ### Kern Pairs from a WOFF Font `get_kern_pairs()` returns all kern pairs embedded in the font. Each `KernPair` carries `left` (GlyphId), `right` (GlyphId), and `value` (int, in font units): ```python from aspose_font import FontLoader font = FontLoader.open("MyFont.woff") pairs = font.get_kern_pairs() print(f"Kern pairs: {len(pairs)}") for pair in pairs[:5]: print(f" {pair.left} + {pair.right} = {pair.value}") ``` Kern pairs are stored in the inner TTF’s `kern` table. Fonts that provide OpenType `GPOS` kern features instead of a `kern` table will still return an empty list from this method. --- ### Format Conversion `FontConverter.convert` converts between font formats. Use the `FontType` enum to specify the target format, then call `to_bytes()` to serialise: ```python from aspose_font.loader import FontLoader from aspose_font.converter import FontConverter from aspose_font import FontType from pathlib import Path # TTF -> WOFF ttf = FontLoader.open("MyFont.ttf") woff = FontConverter.convert(ttf, FontType.WOFF) Path("MyFont.woff").write_bytes(woff.to_bytes(FontType.WOFF)) # TTF -> WOFF2 (Brotli-compressed) woff2 = FontConverter.convert(ttf, FontType.WOFF2) Path("MyFont.woff2").write_bytes(woff2.to_bytes(FontType.WOFF2)) # WOFF -> WOFF2 existing_woff = FontLoader.open("MyFont.woff") converted = FontConverter.convert(existing_woff, FontType.WOFF2) Path("MyFont-from-woff.woff2").write_bytes(converted.to_bytes(FontType.WOFF2)) # WOFF2 -> WOFF (decompress back to WOFF 1) existing_woff2 = FontLoader.open("MyFont.woff2") woff1 = FontConverter.convert(existing_woff2, FontType.WOFF) Path("MyFont-from-woff2.woff").write_bytes(woff1.to_bytes(FontType.WOFF)) ``` All four conversion paths (TTF to WOFF, TTF to WOFF2, WOFF to WOFF2, WOFF2 to WOFF) are supported by the same `FontConverter.convert` API. --- ### Building a Web Font Package `WebFontBuilder.build` generates a complete web font package from a single TTF source, returning a `WebFontBundle` with the CSS, HTML, and font assets. Call `write_to` on the bundle to save the package to disk: ```python from aspose_font.web import WebFontBuilder from aspose_font.loader import FontLoader # Load a TTF source font font = FontLoader.open("MyFont.ttf") # Build the web font bundle (WOFF + WOFF2 assets, CSS, HTML) bundle = WebFontBuilder.build( font=font, file_stem="MyFont", include_woff=True, font_display="swap", preview_text="The quick brown fox", instance_coordinates=None, ) # Write the bundle's assets, CSS, and HTML to disk written_paths = bundle.write_to("web-output") print(f"Wrote {len(written_paths)} files to web-output/") ``` `write_to` returns the list of file paths it wrote. The `font_display` parameter maps directly to the CSS `font-display` descriptor and accepts `"auto"`, `"block"`, `"swap"`, `"fallback"`, or `"optional"`. --- ## Quick Start Install the library: Load a WOFF font and convert it to WOFF2: ```python from aspose_font.loader import FontLoader from aspose_font.converter import FontConverter from aspose_font import FontType from pathlib import Path # Load WOFF font = FontLoader.open("MyFont.woff") print(f"Font : {font.font_name}") print(f"Glyphs : {font.num_glyphs}") print(f"Type : {font.font_type}") # Inspect metadata (if present) — WoffFont-specific property xml = getattr(font, "metadata_xml", None) print(f"Has metadata: {xml is not None}") # Access inner OpenType tables — WoffFont-specific property inner = getattr(font, "inner_font") tables = inner.ttf_tables print(f"Units/em: {tables.head.units_per_em}") # Convert to WOFF2 woff2 = FontConverter.convert(font, FontType.WOFF2) Path("MyFont.woff2").write_bytes(woff2.to_bytes(FontType.WOFF2)) print("Converted to WOFF2") ``` --- ## Supported Web Font Formats | Format | Extension | Load | Convert to WOFF | Convert to WOFF2 | |--------|-----------|------|-----------------|------------------| | TTF | .ttf | Yes | Yes | Yes | | OTF | .otf | Yes | Yes | Yes | | WOFF | .woff | Yes | — | Yes | | WOFF2 | .woff2 | Yes | Yes | — | | EOT | .eot | Yes | Yes | Yes | | CFF | .cff | Yes | Yes | Yes | | TYPE1 | .pfb/.pfa | Yes | Yes | Yes | All source formats support conversion to WOFF and WOFF2 via `FontConverter.convert`. --- ## Open Source and Licensing Aspose.Font FOSS for Python is released under the MIT License. You can use it in personal, commercial, and open-source projects at no cost. The source code is available on GitHub, packaged as `aspose-font`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/font/python/getting-started/) - [Developer Guide](https://docs.aspose.org/font/python/developer-guide/) - [KB Articles](https://kb.aspose.org/font/python/) - [WOFF How-To Guide](https://kb.aspose.org/font/python/how-to-work-with-woff-python/) - [API Reference](https://reference.aspose.org/font/python/) ## Related Resources - [Aspose.Font — Enterprise Blog](https://blog.aspose.com/) --- # Deep Dive: The CSSOM in Python URL: https://blog.aspose.org/html/python/html-cssom-in-python/ How Aspose.HTML FOSS for Python resolves CSS: parse stylesheets with CSSStyleSheet, set inline declarations, apply !important, and read computed styles that honour specificity, importance, and inheritance. --- Product: html Platform: python Page Type: index Canonical URL: https://blog.aspose.org/html/python/html-cssom-in-python/ --- # Deep Dive: The CSSOM in Python ## Introduction Most HTML tooling stops at the tree. Aspose.HTML FOSS for Python goes one layer further: it implements the CSS object model, so a stylesheet is not just text you carry around — it participates in a real cascade, and every element can tell you the style it actually ends up with. This deep dive covers the CSSOM layer: parsing stylesheets with `CSSStyleSheet`, editing declarations through `CSSStyleDeclaration`, and reading results back with `Element.get_computed_style()` — including how specificity, `!important`, and inheritance interact. The library is distributed as `aspose-html-foss`, MIT licensed, and pure Python (3.10+), which makes it practical for style verification in test suites and services where a headless browser would be overkill. --- ## Key Features ### Parse and Attach Stylesheets `CSSStyleSheet.replace_sync()` parses stylesheet text in place; `Document.attach_style_sheet()` registers the sheet with the document so it participates in the cascade. Sheets can also be built rule-by-rule with `insert_rule()`, `add_rule()`, and `remove_rule()`, or created from text with `from_text()`: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() sheet = CSSStyleSheet() sheet.replace_sync("div { color: red }") doc.attach_style_sheet(sheet) ``` ### Specificity Decides the Winner When several rules target the same element, the computed value follows selector specificity. An ID selector (specificity 1,0,0) outranks a class selector (0,1,0): ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") el.set_attribute("class", "foo") el.set_attribute("id", "bar") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync(".foo { color: red } #bar { color: blue }") doc.attach_style_sheet(sheet) print(el.get_computed_style().get_property_value("color")) ``` ### Inline Declarations and CSSStyleDeclaration Each element's `style` property is a live `CSSStyleDeclaration`. Declarations are edited with `set_property()` and inspected with `get_property_value()`, `get_property_priority()`, and `item()`. Inline declarations carry (1,0,0) specificity, so they beat type and class rules from author stylesheets: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync("div { color: red }") doc.attach_style_sheet(sheet) inline = el.style inline.set_property("color", "blue") print(el.get_computed_style().get_property_value("color")) ``` ### Importance Outranks Specificity `!important` inverts the usual outcome: an author rule marked `!important` beats a non-important inline declaration, regardless of specificity. Priorities can also be set programmatically with `set_property_priority()`: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync("div { color: red !important }") doc.attach_style_sheet(sheet) inline = el.style inline.set_property("color", "blue") print(el.get_computed_style().get_property_value("color")) ``` ### Inheritance and the inherit Keyword Inheritable properties like `color` flow from parent to child unless the child has its own local value — a local rule always overrides an inherited one. The explicit `inherit` keyword copies the parent's computed value, and on a root element with no parent it falls back to the property's initial value: ```python from aspose_html.dom import Document doc = Document() el = doc.create_element("div") doc.append_child(el) inline = el.style inline.set_property("color", "inherit") print(el.get_computed_style().get_property_value("color")) ``` --- ## Quick Start Install it with the command below: Resolve a three-way conflict — class rule vs. ID rule vs. inline declaration: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") el.set_attribute("class", "foo") el.set_attribute("id", "bar") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync(".foo { color: red } #bar { color: green }") doc.attach_style_sheet(sheet) inline = el.style inline.set_property("color", "blue") print(el.get_computed_style().get_property_value("color")) ``` --- ## Open Source & Licensing Aspose.HTML FOSS for Python is distributed under the MIT license — commercial use, modification, and redistribution are permitted. Source is on [GitHub](https://github.com/aspose-html-foss/Aspose.HTML-FOSS-for-Python), packaged as `aspose-html-foss`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/html/python/getting-started/) - [Developer Guide](https://docs.aspose.org/html/python/developer-guide/) - [KB Articles](https://kb.aspose.org/html/python/) - [API Reference](https://reference.aspose.org/html/python/) - [Product Overview](https://products.aspose.org/html/python/) ## Related Resources - [Aspose.HTML — Enterprise Blog](https://blog.aspose.com/) --- # Working with the HTML DOM in Python URL: https://blog.aspose.org/html/python/html-dom-python/ Build, traverse, and modify HTML documents in Python with Aspose.HTML FOSS. Create elements and text nodes, manage attributes, move subtrees with Node operations, and parse fragments — all through a standards-based DOM API. --- Product: html Platform: python Page Type: index Canonical URL: https://blog.aspose.org/html/python/html-dom-python/ --- # Working with the HTML DOM in Python ## Introduction The DOM layer is the core of Aspose.HTML FOSS for Python. It models an HTML page the way the standards do — as a tree of `Document`, `Element`, `Text`, `Comment`, and `DocumentFragment` nodes — and gives you the operations to build, inspect, and rearrange that tree from Python code, without a browser in the loop. This post walks through the main DOM features: creating nodes, managing attributes, moving subtrees around with `Node` operations, parsing fragments, and looking elements up again once the tree is built. Everything shown here ships in the `aspose-html-foss` package, is MIT licensed, and runs in pure Python on version 3.10 or later. --- ## Key Features ### Create Documents and Elements `Document` is the node factory: `create_element()` for elements, `create_text_node()` for text, `create_comment()` for comments, and `create_document_fragment()` for lightweight containers. New nodes attach to the tree with `append_child()`: ```python from aspose_html.dom import Document doc = Document() el = doc.create_element("div") doc.append_child(el) ``` ### Manage Attributes Attributes round-trip through `Element.set_attribute()`, `get_attribute()`, `has_attribute()`, and `remove_attribute()`. The `Attr` class models individual attribute nodes when you need them as objects rather than strings: ```python from aspose_html.dom import Document doc = Document() el = doc.create_element("div") el.set_attribute("class", "foo") el.set_attribute("id", "bar") doc.append_child(el) ``` ### Tree Operations on Node Every node inherits the standard tree toolkit from `Node`: `insert_before()`, `remove_child()`, `replace_child()`, `clone_node()`, and `contains()` for structure changes and checks, plus `child_nodes`, `parent_node`, and `first_child` for traversal, and `text_content` for reading or assigning the text of a subtree. `get_root_node()` and `has_child_nodes()` answer the common structural questions directly. ### Parse Fragments and Adjacent Markup `HTMLDocument.parse()` handles complete pages and `HTMLDocument.parse_fragment()` handles partial markup. For surgical insertion relative to an existing element, `Element` provides `insert_adjacent_html()`, `insert_adjacent_text()`, and `insert_adjacent_element()` — the standard four-position insertion API. `Document.import_node()` and `adopt_node()` move nodes between documents. ### Look Up and Read Back `Document.get_element_by_id()` retrieves an element by its `id` attribute. Combined with computed-style access from the CSSOM layer, you can verify what a subtree contains and how it will be styled: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") el.set_attribute("id", "bar") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync("#bar { color: blue }") doc.attach_style_sheet(sheet) style = el.get_computed_style() print(style.get_property_value("color")) ``` --- ## Quick Start Install it with the command below: Build a small tree, tag it with attributes, and confirm the structure: ```python from aspose_html.dom import Document doc = Document() container = doc.create_element("div") container.set_attribute("id", "content") doc.append_child(container) child = doc.create_element("p") container.append_child(child) print(container.has_child_nodes()) print(doc.get_element_by_id("content").get_attribute("id")) ``` --- ## Open Source & Licensing Aspose.HTML FOSS for Python is MIT licensed — free for commercial use, modification, and redistribution. The code lives on [GitHub](https://github.com/aspose-html-foss/Aspose.HTML-FOSS-for-Python), packaged as `aspose-html-foss`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/html/python/getting-started/) - [Developer Guide](https://docs.aspose.org/html/python/developer-guide/) - [KB Articles](https://kb.aspose.org/html/python/) - [API Reference](https://reference.aspose.org/html/python/) - [Product Overview](https://products.aspose.org/html/python/) ## Related Resources - [Aspose.HTML — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.HTML FOSS for Python URL: https://blog.aspose.org/html/python/introducing-html-foss-python/ Aspose.HTML FOSS for Python is a free, MIT-licensed library for parsing HTML into a standards-based DOM, applying CSS stylesheets, and computing styles. It also includes URL parsing and character-encoding detection, implemented in pure Python. --- Product: html Platform: python Page Type: index Canonical URL: https://blog.aspose.org/html/python/introducing-html-foss-python/ --- # Introducing Aspose.HTML FOSS for Python ## Introduction Aspose.HTML FOSS for Python is a new open-source library for working with HTML documents in Python. It parses markup into a standards-based document object model, lets you build and modify element trees programmatically, and resolves CSS — including specificity, inline declarations, and inheritance — into computed styles you can read back from any element. The library targets backend and tooling scenarios where a browser is unavailable or unwanted: services that clean up stored HTML, pipelines that restructure page fragments, and test suites that assert on generated markup. It is distributed as `aspose-html-foss`, is MIT licensed, and is implemented in pure Python for Python 3.10 and later, so it behaves the same on developer machines, CI runners, and servers. Beyond the DOM and CSS core, the package ships practical building blocks that HTML processing usually ends up needing anyway: an HTML tokenizer and tree builder you can drive directly, WHATWG-style `URL` and `URLSearchParams` classes, and a byte-stream encoding detector. --- ## What's Included ### Build and Modify the DOM The DOM layer is built around `Document`, `Element`, and `Node`. Create elements with `Document.create_element()`, wire them together with `append_child()`, set markup attributes with `Element.set_attribute()`, and look nodes up again with `Document.get_element_by_id()`. Full pages and fragments parse through `HTMLDocument.parse()` and `HTMLDocument.parse_fragment()`. ```python from aspose_html.dom import Document doc = Document() el = doc.create_element("div") el.set_attribute("class", "foo") el.set_attribute("id", "bar") doc.append_child(el) ``` ### Apply Stylesheets and Read Computed Styles `CSSStyleSheet.replace_sync()` parses stylesheet text, `Document.attach_style_sheet()` puts it in play, and `Element.get_computed_style()` resolves the cascade. The result honours selector specificity — here the ID rule beats the class rule: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") el.set_attribute("class", "foo") el.set_attribute("id", "bar") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync(".foo { color: red } #bar { color: blue }") doc.attach_style_sheet(sheet) style = el.get_computed_style() print(style.get_property_value("color")) ``` ### Inline Declarations and the Cascade Each element exposes a live `CSSStyleDeclaration` through its `style` property. Inline declarations set with `set_property()` carry higher specificity than author stylesheet rules, and `get_computed_style()` reflects that: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync("div { color: red }") doc.attach_style_sheet(sheet) inline = el.style inline.set_property("color", "blue") print(el.get_computed_style().get_property_value("color")) ``` ### Tokenizer and Tree Builder When you need more control than a finished tree, the lower layers are public API. `Tokenizer.tokenize()` and `Tokenizer.tokenize_fragment()` emit the token stream for a piece of markup, `TreeBuilder.run()` performs standards-based tree construction, and the `parse_html()` function goes from markup to tree in one call. These are the same components the high-level parse path uses. ### URLs and Character Encodings `URL.parse()` and `URL.can_parse()` handle WHATWG-style URL parsing and validation, with `URLSearchParams` (`append()`, `get()`, `has()`, `delete()`) for query strings. For raw bytes, `detect_encoding()` sniffs the encoding — byte-order marks included — and returns the decoded text alongside a confidence level, while `get_canonical_name()` normalizes encoding labels: ```python from aspose_html.encoding.detection import detect_encoding result = detect_encoding(b"\xef\xbb\xbfx") print(result.encoding) print(result.confidence) print(result.text) ``` --- ## Quick Start Install it with the command below: Then build a document, style it, and read the computed result: ```python from aspose_html.dom import Document from aspose_html.cssom import CSSStyleSheet doc = Document() el = doc.create_element("div") el.set_attribute("id", "bar") doc.append_child(el) sheet = CSSStyleSheet() sheet.replace_sync("#bar { color: blue }") doc.attach_style_sheet(sheet) style = el.get_computed_style() print(style.get_property_value("color")) ``` --- ## Open Source & Licensing Aspose.HTML FOSS for Python is released under the MIT license, so commercial use, modification, and redistribution are all permitted. The source code is available on [GitHub](https://github.com/aspose-html-foss/Aspose.HTML-FOSS-for-Python), packaged as `aspose-html-foss`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/html/python/getting-started/) - [Developer Guide](https://docs.aspose.org/html/python/developer-guide/) - [KB Articles](https://kb.aspose.org/html/python/) - [FAQ](https://kb.aspose.org/html/python/faq/) - [API Reference](https://reference.aspose.org/html/python/) - [Product Overview](https://products.aspose.org/html/python/) ## Related Resources - [Aspose.HTML — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Imaging FOSS for .NET URL: https://blog.aspose.org/imaging/net/ --- Product: imaging Platform: net Page Type: index Canonical URL: https://blog.aspose.org/imaging/net/ --- # Aspose.Imaging FOSS for .NET ## Related Topics - [Introducing Aspose.Imaging FOSS for .NET](https://blog.aspose.org/imaging/net/introducing-imaging-foss-net/) --- # Introducing Aspose.Imaging FOSS for .NET URL: https://blog.aspose.org/imaging/net/introducing-imaging-foss-net/ Aspose.Imaging FOSS for .NET is a free, MIT-licensed, zero-dependency library that detects an image file's format and reads its header metadata — dimensions, bit depth, and frame count — without decoding a single pixel. It covers 11 formats, including three with no other FOSS .NET detector: PSD, EMF/WMF, and DICOM. --- Product: imaging Platform: net Page Type: index Canonical URL: https://blog.aspose.org/imaging/net/introducing-imaging-foss-net/ --- # Introducing Aspose.Imaging FOSS for .NET ## Introduction Aspose.Imaging FOSS for .NET is a free, MIT-licensed, open-source library for .NET developers who need to know what an image file *is* — its format, dimensions, bit depth, and frame count — without paying the cost of decoding it. The static `ImageProbe` class is the entry point: `ProbeFile(path)` reads from disk, `Probe(stream)` and `Probe(data)` accept a stream or byte array, and `DetectFormat(stream)` / `DetectFormat(data)` return the `ImageFormat` enum value without building a full `ImageInfo`, for callers that only need to branch on format. Every probe method returns an `ImageInfo` object with nullable `Width`, `Height`, `BitDepth`, and `FrameCount` properties, populated only when the detected format's header actually carries that value. This is a deliberately narrow tool, and that's the point. It does not decode pixels, render images, or convert between formats — for that, the commercial Aspose.Imaging for .NET product is the right choice (linked below under Open Source & Licensing). What Aspose.Imaging FOSS for .NET does is the much smaller, much more common job of answering "what format is this, and how big is it?" as fast and as safely as possible, for the class of problem where full decoding would be wasted work: validating an upload, sizing a thumbnail layout, triaging a batch of mixed files, or reading DICOM header fields for a pre-processing check. The library is MIT-licensed with zero external dependencies and targets both `netstandard2.0` and `net8.0` — free for both open-source and commercial use, with no royalties or redistribution restrictions. --- ## Key Features ### Three Ways to Probe a File `ImageProbe` offers file-path, stream, and byte-array entry points, so it fits wherever the image data already lives in your pipeline — on disk, already in memory, or arriving over the wire. `DetectFormat` skips building a full `ImageInfo` when you only need to branch on format. ```csharp using Aspose.Imaging.Foss; var fromPath = ImageProbe.ProbeFile("photo.jpg"); var fromBytes = ImageProbe.Probe(byteArray); var fromStream = ImageProbe.Probe(stream); var formatOnly = ImageProbe.DetectFormat(byteArray); // ImageFormat only, no header parse ``` ### Structured, Honest Results `ImageInfo` exposes `Format` (an `ImageFormat` enum value, always set once the header is recognized) alongside nullable `Width`, `Height`, `BitDepth`, and `FrameCount`. "Nullable" is doing real work here: field population genuinely varies by format, and `ImageInfo` never fabricates a value a format's header doesn't carry. Checking for `null` before use is the correct pattern, not a defensive afterthought. ```csharp var info = ImageProbe.ProbeFile("scan.dcm"); if (info.Width.HasValue && info.Height.HasValue) { Console.WriteLine($"{info.Format}: {info.Width}x{info.Height}"); } ``` ### 11 Formats, Including Three Nothing Else in the FOSS .NET Space Detects PNG, JPEG, GIF, BMP, WebP (lossy, lossless, and extended), ICO, TIFF, PSD, EMF, WMF, and DICOM. Field population differs by format on purpose, not by omission — PNG carries width, height, bit depth, *and* frame count (though `FrameCount` is a hardcoded `1`, not real animated-PNG frame detection); JPEG and BMP carry dimensions and bit depth but never a frame count; WebP carries only dimensions; ICO's `FrameCount` is a genuine count of the embedded icon sizes in its directory, and a `0` byte in an ICO directory entry's dimension field means 256px, per the format spec; TIFF's `FrameCount` reflects a bounded walk of the file's IFD chain, one IFD per page. Three of these eleven — PSD, EMF/WMF, and DICOM — have no other free, open-source .NET detector that we're aware of, which is a real part of why this library exists. ### WMF and EMF: Two Legacy Formats, Two Different Limits Non-placeable WMF is still correctly identified as `ImageFormat.Wmf`, but only placeable WMF populates dimensions — derived from the header's units-per-inch bounds via a hardcoded 96 DPI conversion, since WMF itself carries no absolute pixel size. EMF has no explicit width/height field at all; its dimensions come from the `rclBounds` device-space rectangle in the EMF header instead. Both are honestly reflected in `ImageInfo`: when a value can't be derived, the property stays `null` rather than guessing. ### DICOM Header Parsing Without a Viewer `ImageProbe` reads DICOM headers across Implicit VR Little Endian and Explicit VR Little/Big Endian transfer syntaxes, extracting `Rows` into `Height`, `Columns` into `Width`, and `BitsAllocated` into `BitDepth` — no DICOM viewer or external imaging dependency required. Parsing is conservative by design: an undefined-length sequence element stops the walk rather than guessing at its contents, so a partially-understood DICOM file degrades to a partial `ImageInfo` instead of a wrong one. ### Never Throws on Malformed or Truncated Input `Probe` is built for untrusted, partial, or in-flight files. If a file matches a format's signature but its header can't be fully parsed — a truncated download, a corrupted upload — the result carries just the detected `Format` rather than an exception. ```csharp byte[] truncated = fullFileBytes[..^3]; var info = ImageProbe.Probe(truncated); // info.Format is still populated; other fields may be null ``` --- ## Quick Start Install the package, then probe a file from disk to read its detected format, dimensions, bit depth, and frame count in one call, followed by a format-only check using the raw bytes: ```csharp using Aspose.Imaging.Foss; var info = ImageProbe.ProbeFile("photo.jpg"); Console.WriteLine($"{info.Format}: {info.Width}x{info.Height}, {info.BitDepth}-bit, " + $"{info.FrameCount ?? 0} frame(s)"); // Format-only detection when dimensions aren't needed var bytes = File.ReadAllBytes("photo.jpg"); var format = ImageProbe.DetectFormat(bytes); ``` --- ## Supported Formats Aspose.Imaging FOSS for .NET **detects** all 11 formats below and reads header-level metadata — it does not decode pixel data, so there is no "write" capability to report. Field population varies by format; see the detailed breakdown in Key Features above. | Format | Extension | Detected | Width / Height | Bit depth | Frame count | |---|---|:---:|:---:|:---:|:---:| | PNG | .png | ✓ | ✓ | ✓ | ✓ | | JPEG | .jpg / .jpeg | ✓ | ✓ | ✓ | — | | GIF | .gif | ✓ | ✓ | — | ✓ | | BMP | .bmp | ✓ | ✓ | ✓ | — | | WebP | .webp | ✓ | ✓ | — | — | | ICO | .ico | ✓ | ✓ | ✓ | ✓ | | TIFF | .tif / .tiff | ✓ | ✓ | ✓ | ✓ | | PSD | .psd | ✓ | ✓ | ✓ | — | | EMF | .emf | ✓ | ✓ (from bounds) | — | — | | WMF | .wmf | ✓ | ✓ (placeable only, 96 DPI) | — | — | | DICOM | .dcm | ✓ | ✓ (Rows/Columns) | ✓ (BitsAllocated) | — | --- ## Open Source & Licensing Aspose.Imaging FOSS for .NET is MIT-licensed with zero external dependencies. MIT licensing permits use in both open-source and commercial projects with no royalties or restrictions on redistribution. The source is available on [GitHub](https://github.com/aspose-imaging-foss/Aspose.Imaging-Foss-for-.NET). It is intentionally scoped to format detection only — for decoding, editing, or converting these image formats, see [Aspose.Imaging for .NET — Enterprise Product](https://products.aspose.com/imaging/net/). --- ## Getting Started - [Getting Started](https://docs.aspose.org/imaging/net/getting-started/) - [Developer Guide](https://docs.aspose.org/imaging/net/developer-guide/) - [KB Articles](https://kb.aspose.org/imaging/net/) - [API Reference](https://reference.aspose.org/imaging/net/) - [Product Page](https://products.aspose.org/imaging/net/) ## Related Resources - [Aspose.Imaging — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Note FOSS for Python URL: https://blog.aspose.org/note/python/ --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/ --- # Aspose.Note FOSS for Python ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) ## Related Topics - [Extract Text from OneNote Files Using Python](https://blog.aspose.org/note/python/extract-text-onenote-python/) - [Introducing Aspose.Note FOSS for Python](https://blog.aspose.org/note/python/introducing-aspose-note-foss-for-python/) - [Getting Started with Aspose.Note FOSS for Python](https://blog.aspose.org/note/python/introducing-note-foss-python/) - [Aspose.Note FOSS for Python — Key Features](https://blog.aspose.org/note/python/note-key-features-python/) - [Parse OneNote Tables in Python — Extract Structured Data from .one Files](https://blog.aspose.org/note/python/parse-onenote-tables-python/) - [Exporting OneNote Files to PDF in Python](https://blog.aspose.org/note/python/python-onenote-pdf-export/) - [Reading OneNote .one Files in Python with Aspose.Note FOSS](https://blog.aspose.org/note/python/python-onenote-reader-pypi/) - [Traversing the OneNote Document Tree in Python](https://blog.aspose.org/note/python/python-onenote-tree-traversal/) --- # Extract Text from OneNote Files Using Python URL: https://blog.aspose.org/note/python/extract-text-onenote-python/ Step-by-step guide to extracting plain text, formatted runs, and hyperlinks from Microsoft OneNote .one files using the free Aspose.Note FOSS Python library. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/extract-text-onenote-python/ --- # Extract Text from OneNote Files Using Python ## Extract Text from OneNote Files Using Python If you need to read text from Microsoft OneNote `.one` files in a Python script, without installing Microsoft Office or running Windows, **Aspose.Note FOSS for Python** is the solution. It is a 100% free, open-source library that parses the OneNote binary format directly and exposes a clean Python API. ### Install No API key. No license file. No Microsoft Office. --- ## The Simplest Approach: GetChildNodes(RichText) OneNote text is stored in `RichText` nodes distributed across pages, outlines, and outline elements. `GetChildNodes(RichText)` performs a recursive search of the entire document tree and returns every text node as a flat list: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") for rt in doc.GetChildNodes(RichText): if rt.Text: print(rt.Text) ``` This is the fastest way to get all text content out of a `.one` file. --- ## Save Text to a File ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") lines = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text] with open("extracted.txt", "w", encoding="utf-8") as f: f.write("\n".join(lines)) print(f"Saved {len(lines)} text blocks to extracted.txt") ``` --- ## Extract Text Per Page When you need to know which page each text block came from: ```python from aspose.note import Document, Page, RichText doc = Document("MyNotes.one") for page in doc.GetChildNodes(Page): title = ( page.Title.TitleText.Text if page.Title and page.Title.TitleText else "(untitled)" ) page_texts = [rt.Text for rt in page.GetChildNodes(RichText) if rt.Text] print(f"\n=== {title} ===") for text in page_texts: print(text) ``` --- ## Extract Hyperlinks Hyperlinks are stored on individual `TextRun` objects within `RichText` nodes. Check `run.Style.IsHyperlink`: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") for rt in doc.GetChildNodes(RichText): for run in rt.TextRuns: if run.Style.IsHyperlink and run.Style.HyperlinkAddress: print(f"{run.Text!r} -> {run.Style.HyperlinkAddress}") ``` --- ## Detect Formatting: Bold, Italic, Underline Each `TextRun` carries per-character formatting through its `TextStyle`: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") for rt in doc.GetChildNodes(RichText): for run in rt.TextRuns: s = run.Style if any([s.IsBold, s.IsItalic, s.IsUnderline]): flags = ", ".join(f for f, v in [ ("bold", s.IsBold), ("italic", s.IsItalic), ("underline", s.IsUnderline) ] if v) print(f"[{flags}] {run.Text.strip()!r}") ``` --- ## Read from a Stream Works with cloud storage, HTTP response bodies, or in-memory buffers: ```python import io, urllib.request from aspose.note import Document, RichText ##Example: load from bytes already in memory one_bytes = open("MyNotes.one", "rb").read() doc = Document(io.BytesIO(one_bytes)) texts = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text] print(f"Extracted {len(texts)} text block(s)") ``` --- ## Windows Encoding Fix On Windows terminals, `sys.stdout` may use a legacy encoding that crashes on Unicode characters. Add this at the start of your script: ```python import sys if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(encoding="utf-8", errors="replace") ``` --- ## What the Library Supports | Feature | Supported | |---|---| | Read `.one` files (path or stream) | Yes | | Extract `RichText.Text` (plain text) | Yes | | Inspect `TextRun.Style` (bold, italic, hyperlink, font) | Yes | | Extract text from table cells | Yes | | Read page titles | Yes | | Write back to `.one` | No | | Encrypted documents | No | --- ## Next Steps - [Full text extraction guide](https://docs.aspose.org/note/python/developer-guide/text-extraction/) - [How-to: Extract Text (KB)](https://kb.aspose.org/note/python/how-to-extract-text-from-onenote-python/) - [How-to: Export to PDF](https://kb.aspose.org/note/python/how-to-export-onenote-to-pdf-python/) - [API Reference](https://reference.aspose.org/note/python/) ## Getting Started - [Getting Started](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [KB Articles](https://kb.aspose.org/note/python/) - [API Reference](https://reference.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Note FOSS for Python URL: https://blog.aspose.org/note/python/introducing-aspose-note-foss-for-python/ Aspose.Note FOSS for Python is now available on PyPI. Work with OneNote .one files in Python — text extraction, image access, table traversal, and PDF generation (export-only). MIT-licensed, no Microsoft Office required. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/introducing-aspose-note-foss-for-python/ --- # Introducing Aspose.Note FOSS for Python ## Introduction Aspose.Note FOSS for Python is a free, MIT-licensed library for reading Microsoft OneNote `.one` files in Python. It provides a complete document object model (DOM) for traversing pages, extracting text and images, parsing tables, and writing PDF output files — all without Microsoft Office or any proprietary runtime. Install with a single pip command: --- ## Aspose.Note FOSS for Python Is Now Available We are pleased to announce the availability of **Aspose.Note FOSS for Python** on PyPI. This free, open-source library lets Python developers read Microsoft OneNote `.one` section files, traverse their full document object model, extract content, and export to PDF, without requiring Microsoft Office or any proprietary runtime. Install it now: For PDF export: --- ## What Is Aspose.Note FOSS for Python? Aspose.Note FOSS for Python is a 100% free, MIT-licensed Python library that provides an **Aspose.Note-shaped public API** (`aspose.note.*`) for reading Microsoft OneNote `.one` files. It is backed by a built-in pure-Python MS-ONE/OneStore binary parser, with no COM interop, no platform-native DLL, and no Microsoft Office installation required. The API surface is modeled after [Aspose.Note for .NET](https://products.aspose.com/note/net/), making the transition familiar for teams already using Aspose products on other platforms. --- ## Key Capabilities ### Read Any .one File Load OneNote 2010, OneNote Online, and OneNote 2007 section files from a file path or any binary stream: ```python from aspose.note import Document doc = Document("MyNotes.one") ``` ### Traverse the Full Document DOM The library exposes a complete document object model: `Document → Page → Outline → OutlineElement → RichText / Image / Table / AttachedFile`. Use `GetChildNodes(Type)` for recursive, type-filtered searches: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") all_text = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text] ``` ### Extract Text with Rich Formatting Every `RichText` node contains a list of `TextRun` segments. Each run carries per-character `TextStyle` metadata: bold, italic, underline, font name, font color, hyperlink address, and more: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") for rt in doc.GetChildNodes(RichText): for run in rt.TextRuns: if run.Style.IsHyperlink: print(f" Link: {run.Text} -> {run.Style.HyperlinkAddress}") elif run.Style.IsBold: print(f" Bold: {run.Text}") ``` ### Save Images and Attachments Retrieve embedded images as raw bytes with filename and dimensions. Save attached files to disk: ```python from aspose.note import Document, Image, AttachedFile doc = Document("MyNotes.one") for img in doc.GetChildNodes(Image): with open(img.FileName or "image.bin", "wb") as f: f.write(img.Bytes) for af in doc.GetChildNodes(AttachedFile): with open(af.FileName or "attachment.bin", "wb") as f: f.write(af.Bytes) ``` ### Parse Tables Walk `Table → TableRow → TableCell` hierarchies and read cell content: ```python from aspose.note import Document, Table, TableRow, TableCell, RichText doc = Document("MyNotes.one") for table in doc.GetChildNodes(Table): for row in table.GetChildNodes(TableRow): cells = [ " ".join(rt.Text for rt in cell.GetChildNodes(RichText)) for cell in row.GetChildNodes(TableCell) ] print(cells) ``` ### Export to PDF Save any loaded document to PDF using the optional ReportLab backend. Configure image compression and quality with `PdfSaveOptions`: ```python from aspose.note import Document, SaveFormat # ------ Step 1: Open the document ------ doc = Document("MyNotes.one") # ------ Step 2: Write the file (PDF format, export-only) ------ output_path = "output.pdf" doc.Save(output_path, SaveFormat.Pdf) ``` --- ## Supported Content Types | Content | Supported | |---|---| | Pages and page titles | Yes | | Plain text (`RichText.Text`) | Yes | | Formatted runs (bold, italic, underline, font, color) | Yes | | Hyperlinks in text runs | Yes | | Embedded images (bytes, filename, dimensions) | Yes | | Attached files (bytes, filename) | Yes | | Tables (rows, cells, column widths) | Yes | | OneNote tags (NoteTag: `Icon`, `Label`, `Highlight`, `CreationTime`, `CompletedTime`) | Yes | | Numbered and bulleted lists (NumberList) | Yes | | Page metadata (author, creation time, level) | Yes | | PDF export | Yes (ReportLab required) | | Write back to `.one` | Not supported | | Encrypted documents | Not supported | --- ## Familiar API for .NET Developers Teams already using Aspose.Note for .NET will find the Python API immediately recognizable. Core classes such as `Document`, `Page`, `RichText`, `Image`, `DocumentVisitor`, and `SaveFormat` match the .NET equivalents in name and behavior. For scenarios requiring full write support, conversion to additional formats, or encrypted document handling, the commercial [Aspose.Note for .NET](https://products.aspose.com/note/net/) and [Aspose.Note for Java](https://products.aspose.com/note/java/) products are available. --- ## Getting Started Get up and running in three steps: 1. **Install**: 2. **Open**: `doc = Document("notebook.one")` — supports OneNote 2007, 2010, and Online formats 3. **Traverse**: `doc.GetChildNodes(RichText)` — type-filtered recursive search 4. **Export to file**: `doc.Save("output.pdf", SaveFormat.Pdf)` — PDF generation (export-only); requires the `[pdf]` extra (adds ReportLab) The following example demonstrates steps 2 and 3 (no PDF needed): ```python from aspose.note import Document, RichText doc = Document("notebook.one") texts = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text] print("\n".join(texts[:5])) ``` --- ## Quick Start ```python from aspose.note import Document, SaveFormat # ------ Step A: Open the OneNote file ------ doc = Document("MyNotes.one") # ------ Step B: Generate PDF (export-only) ------ # Requires the [pdf] extra (adds ReportLab) -- see Installation Summary below output_file = "output.pdf" doc.Save(output_file, SaveFormat.Pdf) print("PDF generated successfully.") ``` --- ## Installation Summary | Variant | Purpose | |---|---| | Core package | Core library (reading, traversal, DOM access) | | Core with the `[pdf]` extra | Core + PDF export (adds ReportLab) | | Editable install from source | For contributors | **Requirements**: Python 3.10, 3.11, or 3.12. No Microsoft Office required. --- ## Get Started - **PyPI**: https://pypi.org/project/aspose-note/ - **Source code**: https://github.com/aspose-note-foss/Aspose.Note-FOSS-for-Python - **Report issues**: https://github.com/aspose-note-foss/Aspose.Note-FOSS-for-Python/issues - [Getting Started Guide](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [API Reference](https://reference.aspose.org/note/python/) - [KB Articles](https://kb.aspose.org/note/python/) --- # Getting Started with Aspose.Note FOSS for Python URL: https://blog.aspose.org/note/python/introducing-note-foss-python/ A getting-started walkthrough for Aspose.Note FOSS for Python: install the aspose-note package, load a OneNote .one file, read its pages and text, and save a basic PDF — MIT-licensed, no Microsoft Office required. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/introducing-note-foss-python/ --- # Getting Started with Aspose.Note FOSS for Python ## Introduction This guide gets you from `pip install` to a working script in a few minutes. `aspose-note` is a free, MIT-licensed library for reading and saving Microsoft OneNote files entirely in Python, with no dependency on Microsoft Office, COM automation, or any native extension. --- ## What Is Aspose.Note FOSS for Python? OneNote's `.one` format is a proprietary binary container — parsing it without Microsoft's own libraries has traditionally required reverse-engineered tools or Windows-specific COM bridges. Aspose.Note FOSS provides a pure-Python implementation that reads the format and exports to PDF on any platform that supports Python 3.10 or later. The library exposes a document object model: a `Document` root that contains `Page` nodes, each of which may hold `Title`, `Outline`, `RichText`, `Image`, and `AttachedFile` children. You traverse the tree with `GetChildNodes()` and export the result to PDF with `Document.Save()`. For the full capability tour — including building a notebook from scratch — see [Introducing Aspose.Note FOSS for Python](https://blog.aspose.org/note/python/introducing-aspose-note-foss-for-python/). --- ## Quick Start Here is the whole workflow in five lines — load a `.one` file and save it straight to PDF: ```python from aspose.note import Document, SaveFormat # Load a .one file doc = Document("notebook.one") print(f"Format: {doc.FileFormat}") # Save to PDF doc.Save("notebook.pdf", SaveFormat.Pdf) print("Saved notebook.pdf") ``` --- ## Reading Pages and Text Pages are `Page` nodes inside the `Document`. Each `Page` has a `Title` property and can contain `Outline` elements with `RichText` content. Use `GetChildNodes()` to walk the tree: ```python from aspose.note import Document, Page, RichText doc = Document("notebook.one") for page in doc.GetChildNodes(Page): title = page.Title if title and title.TitleText: print(f"Page: {title.TitleText}") for rt in page.GetChildNodes(RichText): text = "".join(rt) if text.strip(): print(f" Text: {text[:80]}") ``` For a deeper look at reading text, images, attachments, and tables, see [Reading OneNote .one Files in Python with Aspose.Note FOSS](https://blog.aspose.org/note/python/python-onenote-reader-pypi/). --- ## Saving to PDF Once you have a loaded `Document`, converting it to PDF is a single call: pass a file path and `SaveFormat.Pdf` to `Document.Save()`, and the library renders the notebook to PDF in-process: ```python from aspose.note import Document, SaveFormat doc = Document("notebook.one") doc.Save("output.pdf", SaveFormat.Pdf) ``` For in-memory buffer output, batch conversion, and the export-only limitation, see [Exporting OneNote Files to PDF in Python](https://blog.aspose.org/note/python/python-onenote-pdf-export/). --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | OneNote 2010 | `.one` | ✓ | — | | OneNote 2007 | `.one` | ✓ | — | | OneNote Online | `.one` | ✓ | — | | PDF | `.pdf` | — | ✓ | --- ## Open Source & Licensing Aspose.Note FOSS for Python is released under the MIT License. The package is published on PyPI as `aspose-note` and commercial use, modification, and redistribution are all permitted under the MIT terms. --- ## Getting Started - [Getting Started](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [KB Articles](https://kb.aspose.org/note/python/) - [API Reference](https://reference.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Note FOSS for Python — Key Features URL: https://blog.aspose.org/note/python/note-key-features-python/ Explore the key features of Aspose.Note FOSS for Python: reading OneNote files, traversing the document tree, exporting to PDF, and working with pages, outlines, and rich text — MIT-licensed, no Microsoft Office required. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/note-key-features-python/ --- # Aspose.Note FOSS for Python — Key Features ## Introduction Aspose.Note FOSS for Python (`aspose-note` on PyPI) is a free, MIT-licensed library for reading Microsoft OneNote `.one` files and exporting to PDF in pure Python. Version 26.3.2 ships with a complete document object model covering pages, outlines, rich-text nodes, images, and attached files — no Microsoft Office installation or Windows dependency required. --- ## Key Features ### Document Loading and Format Detection `Document` is the root of the object model. Pass a file path to load any supported OneNote format. The `FileFormat` property reports which format was detected. ```python from aspose.note import Document, FileFormat doc = Document("notebook.one") print(f"Format : {doc.FileFormat}") print(f"Pages : {len(list(doc))}") ``` ### Traversing Pages and Titles Pages are `Page` nodes directly under the `Document`. Each `Page` exposes metadata such as `Author`, `CreationTime`, and `Title`. The `Title` node in turn provides `TitleText`, `TitleDate`, and `TitleTime` as `RichText` children. ```python from aspose.note import Document, Page doc = Document("notebook.one") for page in doc.GetChildNodes(Page): print(f"Author : {page.Author}") print(f"Created : {page.CreationTime}") if page.Title and page.Title.TitleText: print(f"Title : {page.Title.TitleText}") ``` ### Reading Rich Text Content `RichText` nodes are the leaf nodes that carry the actual text content. Iterate a `RichText` object with a standard `for` loop — each item is a string segment. Use `Append()` to add new text with a style. ```python from aspose.note import Document, Page, Outline, RichText doc = Document("notebook.one") for page in doc.GetChildNodes(Page): for rt in page.GetChildNodes(RichText): text = "".join(rt) if text.strip(): print(text[:120]) ``` ### Outline Layout Properties `Outline` nodes expose layout coordinates: `HorizontalOffset`, `VerticalOffset`, `MaxWidth`, `MaxHeight`, and `MinWidth`. These are useful for layout-aware extraction or re-composition of pages. ```python from aspose.note import Document, Outline doc = Document("notebook.one") for outline in doc.GetChildNodes(Outline): print(f"HOffset={outline.HorizontalOffset} VOffset={outline.VerticalOffset} MaxW={outline.MaxWidth}") ``` ### Document Tree Construction Build a `Document` from scratch using `CompositeNode.AppendChildLast()`. Each node type can be added to its valid parent: `Page` → `Document`, `Outline` → `Page`, `RichText` nodes → `Outline`. ```python from aspose.note import Document, Page, Outline, RichText, ParagraphStyle, Title, SaveFormat doc = Document() page = Page() title_text = RichText() title_text.Append("My New Page", ParagraphStyle()) title = Title() title.TitleText = title_text page.Title = title outline = Outline() page.AppendChildLast(outline) doc.AppendChildLast(page) doc.Save("new_notebook.pdf", SaveFormat.Pdf) ``` ### Exporting to PDF `Document.Save()` accepts `SaveFormat.Pdf` to write a PDF to a file path or a `BytesIO` buffer. The export runs entirely in-process without any external renderer. ```python import io from aspose.note import Document, SaveFormat doc = Document("notebook.one") # File output doc.Save("export.pdf", SaveFormat.Pdf) # In-memory buffer buf = io.BytesIO() doc.Save(buf, SaveFormat.Pdf) print(f"PDF bytes: {len(buf.getvalue())}") ``` --- ## Quick Start ```python from aspose.note import Document, Page, RichText, SaveFormat doc = Document("notebook.one") # Print all text for page in doc.GetChildNodes(Page): for rt in page.GetChildNodes(RichText): print("".join(rt)) # Export to PDF doc.Save("output.pdf", SaveFormat.Pdf) ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | OneNote 2010 | `.one` | ✓ | — | | OneNote 2007 | `.one` | ✓ | — | | OneNote Online | `.one` | ✓ | — | | PDF | `.pdf` | — | ✓ | --- ## Open Source & Licensing Aspose.Note FOSS for Python is released under the MIT License. Install from PyPI as `aspose-note`. Commercial use, redistribution, and modification are all permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [KB Articles](https://kb.aspose.org/note/python/) - [API Reference](https://reference.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) --- # Parse OneNote Tables in Python — Extract Structured Data from .one Files URL: https://blog.aspose.org/note/python/parse-onenote-tables-python/ Learn how to parse and extract table data from Microsoft OneNote .one files using Aspose.Note FOSS for Python. Covers row iteration, cell text, column widths, and CSV export. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/parse-onenote-tables-python/ --- # Parse OneNote Tables in Python — Extract Structured Data from .one Files ## Parse OneNote Tables in Python Microsoft OneNote lets users embed structured tables directly in pages, perfect for task lists, schedules, comparison matrices, and data collection forms. Aspose.Note FOSS for Python makes it possible to extract all of this tabular data programmatically, with no Microsoft Office installation required. ### Install --- ## Load the Document and Find Tables `GetChildNodes(Table)` performs a recursive search across the entire document and returns every table as a `Table` object: ```python from aspose.note import Document, Table doc = Document("MyNotes.one") tables = doc.GetChildNodes(Table) print(f"Found {len(tables)} table(s)") ``` --- ## Read Cell Values Tables follow a three-level hierarchy: `Table → TableRow → TableCell`. Each cell contains `RichText` nodes whose `.Text` gives the plain-text content: ```python from aspose.note import Document, Table, TableRow, TableCell, RichText doc = Document("MyNotes.one") for t_num, table in enumerate(doc.GetChildNodes(Table), start=1): print(f"\nTable {t_num}:") for r_num, row in enumerate(table.GetChildNodes(TableRow), start=1): cells = row.GetChildNodes(TableCell) row_values = [ " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip() for cell in cells ] print(f" Row {r_num}: {row_values}") ``` --- ## Inspect Column Widths `Table.Columns` is a list of `TableColumn` objects; each `TableColumn` has a `.Width` property giving the column width in points: ```python from aspose.note import Document, Table doc = Document("MyNotes.one") for i, table in enumerate(doc.GetChildNodes(Table), start=1): widths = [col.Width for col in table.Columns] print(f"Table {i}: {len(widths)} column(s)") print(f" Widths (pts): {widths}") print(f" Borders visible: {table.IsBordersVisible}") ``` --- ## Export All Tables to CSV Convert every table in the document to CSV format: ```python import csv, io from aspose.note import Document, Table, TableRow, TableCell, RichText doc = Document("MyNotes.one") output = io.StringIO() writer = csv.writer(output) for table in doc.GetChildNodes(Table): for row in table.GetChildNodes(TableRow): values = [ " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip() for cell in row.GetChildNodes(TableCell) ] writer.writerow(values) writer.writerow([]) # blank row between tables with open("tables.csv", "w", encoding="utf-8", newline="") as f: f.write(output.getvalue()) print("Saved tables.csv") ``` --- ## Export Tables to a Python Dict / JSON ```python import json from aspose.note import Document, Table, TableRow, TableCell, RichText doc = Document("MyNotes.one") result = [] for table in doc.GetChildNodes(Table): rows = [] for row in table.GetChildNodes(TableRow): cells = [ " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip() for cell in row.GetChildNodes(TableCell) ] rows.append(cells) result.append({"rows": rows, "column_widths": [col.Width for col in table.Columns]}) print(json.dumps(result, indent=2)) ``` --- ## Use the First Row as Headers ```python from aspose.note import Document, Table, TableRow, TableCell, RichText doc = Document("MyNotes.one") for table in doc.GetChildNodes(Table): rows = table.GetChildNodes(TableRow) if not rows: continue def row_text(row): return [ " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip() for cell in row.GetChildNodes(TableCell) ] headers = row_text(rows[0]) print("Headers:", headers) for row in rows[1:]: record = dict(zip(headers, row_text(row))) print(" Record:", record) ``` --- ## What the Library Supports for Tables | Feature | Supported | |---|---| | `Table.Columns` (each `TableColumn.Width`) | Yes: column widths in points | | `Table.IsBordersVisible` | Yes | | `Table.Tags` | Yes: OneNote tags on tables | | Cell text via `RichText` | Yes | | Cell images via `Image` | Yes | | Merged cells (rowspan/colspan metadata) | Not exposed in public API | | Write/edit tables and save to `.one` | No | --- ## Next Steps - [Table Parsing Developer Guide](https://docs.aspose.org/note/python/developer-guide/tables/) - [How-to: Parse Tables (KB)](https://kb.aspose.org/note/python/how-to-parse-tables-onenote-python/) - [How-to: Extract Text](https://kb.aspose.org/note/python/how-to-extract-text-from-onenote-python/) - [API Reference: Table](https://reference.aspose.org/note/python/table/) ## Getting Started - [Getting Started](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [KB Articles](https://kb.aspose.org/note/python/) - [API Reference](https://reference.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) --- # Exporting OneNote Files to PDF in Python URL: https://blog.aspose.org/note/python/python-onenote-pdf-export/ A deep dive into PDF export with Aspose.Note FOSS for Python — Document.Save() mechanics, tuning output with PdfSaveOptions (JPEG quality, page ranges), file vs. in-memory buffer output, batch conversion, and the export-only limitation. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/python-onenote-pdf-export/ --- # Exporting OneNote Files to PDF in Python ## Introduction `aspose-note` converts Microsoft OneNote `.one` files to PDF entirely in Python — no Microsoft Office, no external PDF renderer. This guide covers the export path in depth: the basic `Document.Save()` call, tuning output with `PdfSaveOptions`, writing to an in-memory buffer, converting a whole folder of notebooks in one pass, and what "export-only" actually means for your workflow. --- ## Basic Export The shortest path from a notebook to a PDF is a two-line call: load the `.one` file into a `Document`, then save it with the `SaveFormat.Pdf` constant — no options object is needed for the default output: ```python from aspose.note import Document, SaveFormat doc = Document("notebook.one") doc.Save("notebook.pdf", SaveFormat.Pdf) ``` --- ## Tuning Output with PdfSaveOptions For anything beyond the default output, pass a `PdfSaveOptions` instance instead of `SaveFormat.Pdf` — `Document.Save()` accepts either. `PdfSaveOptions` defaults to `PageIndex=0` and `PageCount=None` (every page), and exposes `JpegQuality` for embedded image compression: ```python from aspose.note import Document from aspose.note.saving import PdfSaveOptions doc = Document("notebook.one") # Compress embedded images more aggressively opts = PdfSaveOptions(JpegQuality=90) doc.Save("notebook-compressed.pdf", opts) ``` `PageIndex` and `PageCount` export a specific page range instead of the whole notebook — useful for previewing a large notebook or splitting it into smaller PDFs: ```python from aspose.note import Document from aspose.note.saving import PdfSaveOptions doc = Document("notebook.one") # Export 3 pages starting at index 2 opts = PdfSaveOptions(PageIndex=2, PageCount=3) doc.Save("notebook-excerpt.pdf", opts) ``` --- ## Saving to an In-Memory Buffer `Document.Save()` accepts any binary stream in place of a file path, so you can generate a PDF without touching disk — useful when serving the result from a web request or passing it directly to another library: ```python import io from aspose.note import Document from aspose.note.saving import PdfSaveOptions doc = Document("notebook.one") buf = io.BytesIO() doc.Save(buf, PdfSaveOptions()) pdf_bytes = buf.getvalue() print(f"PDF size: {len(pdf_bytes)} bytes") ``` --- ## Batch Converting a Folder of Notebooks The same `Document`/`Save()` pair scales to a directory of files with a plain loop — no batching API is required: ```python import pathlib from aspose.note import Document, SaveFormat source_dir = pathlib.Path("notebooks") output_dir = pathlib.Path("pdf_output") output_dir.mkdir(exist_ok=True) for one_file in source_dir.glob("*.one"): doc = Document(str(one_file)) doc.Save(str(output_dir / f"{one_file.stem}.pdf"), SaveFormat.Pdf) print(f"Converted {one_file.name}") ``` --- ## Export-Only: What It Means in Practice Aspose.Note FOSS for Python reads `.one` files and writes PDF — it does not write back to `.one`. That also applies to notebooks built in-process: see [Aspose.Note FOSS for Python — Key Features](https://blog.aspose.org/note/python/note-key-features-python/) for constructing a `Document` tree from scratch with `AppendChildLast()` — its output path is PDF as well, since `.one` write support is not part of this library. --- ## Getting Started - [Getting Started](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [KB Articles](https://kb.aspose.org/note/python/) - [API Reference](https://reference.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Note — Enterprise Product](https://products.aspose.com/note/) --- # Reading OneNote .one Files in Python with Aspose.Note FOSS URL: https://blog.aspose.org/note/python/python-onenote-reader-pypi/ A focused guide to installing aspose-note from PyPI and reading Microsoft OneNote .one files in Python — opening documents, walking the document tree, and extracting rich text, images, attachments, and tables. MIT-licensed, no Microsoft Office required. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/python-onenote-reader-pypi/ --- # Reading OneNote .one Files in Python with Aspose.Note FOSS ## Introduction `aspose-note` is a free, MIT-licensed Python package for reading Microsoft OneNote `.one` files. This guide covers exactly what you need to install it from PyPI and start reading notebooks: opening a file, walking its document tree, and pulling out rich text, images, attachments, and tables. No Microsoft Office installation, COM automation, or platform-native DLL is required — the package is a pure-Python implementation of the MS-ONE/OneStore binary format, and it runs the same way on Windows, macOS, and Linux. --- ## Opening a .one File Pass a file path (or any binary stream) to `Document` to load a OneNote 2007, 2010, or Online section file: ```python from aspose.note import Document doc = Document("MyNotes.one") ``` --- ## Walking the Document Tree The document is exposed as a tree — `Document → Page → Outline → OutlineElement → RichText / Image / Table / AttachedFile`. `GetChildNodes(Type)` performs a recursive, type-filtered search anywhere in that tree, so you rarely need to walk each level by hand: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") all_text = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text] ``` --- ## Reading Rich Text Each `RichText` node holds a list of `TextRun` segments, and every run carries its own `TextStyle` — bold, italic, underline, font name, font color, and hyperlink address: ```python from aspose.note import Document, RichText doc = Document("MyNotes.one") for rt in doc.GetChildNodes(RichText): for run in rt.TextRuns: if run.Style.IsHyperlink: print(f" Link: {run.Text} -> {run.Style.HyperlinkAddress}") elif run.Style.IsBold: print(f" Bold: {run.Text}") ``` --- ## Reading Images and Attachments `Image` and `AttachedFile` nodes expose their raw bytes and original filename, so both can be written back to disk as-is: ```python from aspose.note import Document, Image, AttachedFile doc = Document("MyNotes.one") for img in doc.GetChildNodes(Image): with open(img.FileName or "image.bin", "wb") as f: f.write(img.Bytes) for af in doc.GetChildNodes(AttachedFile): with open(af.FileName or "attachment.bin", "wb") as f: f.write(af.Bytes) ``` --- ## Parsing Tables Tables nest as `Table → TableRow → TableCell`, and each cell's text is read the same way as any other `RichText` content: ```python from aspose.note import Document, Table, TableRow, TableCell, RichText doc = Document("MyNotes.one") for table in doc.GetChildNodes(Table): for row in table.GetChildNodes(TableRow): cells = [ " ".join(rt.Text for rt in cell.GetChildNodes(RichText)) for cell in row.GetChildNodes(TableCell) ] print(cells) ``` --- ## What's Next This guide covers reading only. To export what you've read to PDF, see [Exporting OneNote Files to PDF in Python](https://blog.aspose.org/note/python/python-onenote-pdf-export/). For a full tour of the library — including building a notebook from scratch — see [Introducing Aspose.Note FOSS for Python](https://blog.aspose.org/note/python/introducing-aspose-note-foss-for-python/). --- ## Getting Started - **PyPI**: https://pypi.org/project/aspose-note/ - **Source code**: https://github.com/aspose-note-foss/Aspose.Note-FOSS-for-Python - **Report issues**: https://github.com/aspose-note-foss/Aspose.Note-FOSS-for-Python/issues - [Getting Started Guide](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [API Reference](https://reference.aspose.org/note/python/) - [KB Articles](https://kb.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Note — Enterprise Product](https://products.aspose.com/note/) --- # Traversing the OneNote Document Tree in Python URL: https://blog.aspose.org/note/python/python-onenote-tree-traversal/ A deep dive into traversal patterns with Aspose.Note FOSS for Python — recursive type-filtered search with GetChildNodes, walking the structural hierarchy by hand, single-pass traversal with DocumentVisitor, and outline layout properties. --- Product: Aspose.Note Platform: python Page Type: index Canonical URL: https://blog.aspose.org/note/python/python-onenote-tree-traversal/ --- # Traversing the OneNote Document Tree in Python ## Introduction The examples below assume `aspose-note` is installed; grab it from PyPI to follow along on your own notebook file: Aspose.Note FOSS for Python exposes a full document object model — `Document → Page → Outline → OutlineElement → RichText / Image / Table / AttachedFile` — and gives you three different ways to walk it. This guide covers each one: recursive type-filtered search with `GetChildNodes()`, walking the hierarchy level by level yourself, and single-pass traversal with a `DocumentVisitor`. --- ## Recursive Search with GetChildNodes `GetChildNodes(Type)` searches recursively from any node downward and returns each descendant of the given type, regardless of how deep it's nested. This is a direct way to answer "find each `RichText` node in this notebook" without caring which page or outline it belongs to: ```python from aspose.note import Document, RichText doc = Document("notebook.one") all_text = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text] ``` Because the search is recursive, calling `doc.GetChildNodes(RichText)` finds text nested inside tables and nested outlines too — you don't need a separate call per container type. --- ## Walking the Hierarchy by Hand When you need to know *which* page or outline a node came from — not just that it exists somewhere — walk the tree level by level instead of searching flat. Each level's `GetChildNodes()` call is scoped to its immediate parent: ```python from aspose.note import Document, Page, Outline, RichText doc = Document("notebook.one") for page in doc.GetChildNodes(Page): title = "".join(page.Title.TitleText) if page.Title and page.Title.TitleText else "Untitled" print(f"Page: {title}") for outline in page.GetChildNodes(Outline): for rt in outline.GetChildNodes(RichText): text = "".join(rt) if text.strip(): print(f" [{title}] {text[:80]}") ``` For deep-diving into what you can extract at each level — text runs, images, attachments, and tables — see [Reading OneNote .one Files in Python with Aspose.Note FOSS](https://blog.aspose.org/note/python/python-onenote-reader-pypi/). --- ## Single-Pass Traversal with DocumentVisitor `DocumentVisitor` is an abstract base class with `VisitXStart`/`VisitXEnd` hook pairs for each node type (`VisitDocumentStart`, `VisitPageStart`, `VisitTitleStart`, `VisitOutlineStart`, `VisitOutlineElementStart`, and their `*End` counterparts). Subclass it, override the hooks you need, and pass an instance to `Document.Accept()` to drive one traversal pass over the whole tree: ```python from aspose.note import Document, DocumentVisitor, Page class TocVisitor(DocumentVisitor): def __init__(self): self.titles = [] def VisitPageStart(self, page: Page): if page.Title and page.Title.TitleText: self.titles.append("".join(page.Title.TitleText)) doc = Document("notebook.one") toc = TocVisitor() doc.Accept(toc) print("\n".join(toc.titles)) ``` Use a visitor instead of `GetChildNodes()` when you need to act on multiple node types in a single pass, or when start/end pairs matter — for example, tracking how deeply nested an outline element is by counting `VisitOutlineStart`/`VisitOutlineEnd` calls. --- ## Outline Layout Properties While traversing `Outline` nodes, you also get their layout coordinates — `HorizontalOffset`, `VerticalOffset`, `MaxWidth`, `MaxHeight`, and `MinWidth` — which are useful for layout-aware extraction or re-composition of a page: ```python from aspose.note import Document, Outline doc = Document("notebook.one") for outline in doc.GetChildNodes(Outline): print(f"HOffset={outline.HorizontalOffset} VOffset={outline.VerticalOffset} MaxW={outline.MaxWidth}") ``` --- ## Which Approach to Use - **`GetChildNodes(Type)`** — you want each node of one type, anywhere in the tree, and don't need to know its ancestors. - **Manual hierarchy walk** — you need parent context (which page, which outline) alongside each node. - **`DocumentVisitor`** — you need a single pass that reacts to several node types at once, or care about entering/leaving a container (start/end pairs). For building a `Document` tree from scratch instead of reading one, see [Aspose.Note FOSS for Python — Key Features](https://blog.aspose.org/note/python/note-key-features-python/). --- ## Getting Started - [Getting Started](https://docs.aspose.org/note/python/getting-started/) - [Developer Guide](https://docs.aspose.org/note/python/developer-guide/) - [KB Articles](https://kb.aspose.org/note/python/) - [API Reference](https://reference.aspose.org/note/python/) ## Related Resources - [Aspose.Note — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Note — Enterprise Product](https://products.aspose.com/note/) --- # Aspose.Page FOSS for Python URL: https://blog.aspose.org/page/python/ --- Product: Aspose.Page Platform: python Page Type: index Canonical URL: https://blog.aspose.org/page/python/ --- # Aspose.Page FOSS for Python Articles and tutorials for Aspose.Page FOSS for Python. ## Related Topics - [Introducing Aspose.Page FOSS for Python](https://blog.aspose.org/page/python/introducing-page-foss-python/) - [Common Rendering and Conversion Utilities in Aspose.Page FOSS for Python](https://blog.aspose.org/page/python/page-common-in-python/) - [Working with PS and EPS Files in Python](https://blog.aspose.org/page/python/page-ps-python/) --- # Introducing Aspose.Page FOSS for Python URL: https://blog.aspose.org/page/python/introducing-page-foss-python/ Aspose.Page FOSS for Python is a free, MIT-licensed library for exporting PostScript, EPS, and XPS documents to PDF and raster images. Install with pip, no Ghostscript or Adobe runtime required. --- Product: Aspose.Page Platform: python Page Type: index Canonical URL: https://blog.aspose.org/page/python/introducing-page-foss-python/ --- # Introducing Aspose.Page FOSS for Python ## Introduction Aspose.Page FOSS for Python is a free, open-source library for converting PostScript (PS), Encapsulated PostScript (EPS), and XPS documents to PDF and raster images in Python applications. It is distributed under the MIT license as `aspose-page-foss`. The library provides two top-level document classes: `PsDocument` for PS and EPS files, and `XpsDocument` for XPS files. Both classes expose `to_pdf()` and `to_image()` methods that return byte arrays, making it straightforward to integrate into file processing pipelines without writing temporary files. Because the library has no dependency on Ghostscript, Adobe Reader, or any native Office runtime, it runs on Windows, Linux, and macOS including CI runners and Docker containers. Developers who need the full commercial API with advanced rendering features can continue using the enterprise Aspose.Page for Python product alongside these open-source utilities. --- ## What's Included ### PS and EPS to PDF Conversion `PsDocument` handles both PostScript (`.ps`) and Encapsulated PostScript (`.eps`) files through the same class interface. Call `PsDocument.from_file()` to load a document, then call `to_pdf()` to obtain the result as a PDF byte array. ```python from pathlib import Path from aspose.page.ps.document import PsDocument ps = PsDocument.from_file("input.ps") pdf_bytes = ps.to_pdf() Path("output.pdf").write_bytes(pdf_bytes) ``` The `from_bytes()` class method accepts raw bytes, so documents arriving from network streams or file uploads can be processed without writing to disk first. ### PS and EPS to Raster Image To render a PS or EPS document to a PNG or JPEG image, pass an `ImageSaveOptions` instance to `to_image()`. Set the `format` property to `"png"` or `"jpeg"` and the `dpi` property to control the output resolution. ```python from aspose.page.ps.document import PsDocument from aspose.page.ps.output import ImageSaveOptions eps = PsDocument.from_file("input.eps") opts = ImageSaveOptions(format="png", dpi=150) png_bytes = eps.to_image(opts) ``` ### XPS to PDF and Image `XpsDocument` loads XPS files and exposes the same `to_pdf()` and `to_image()` interface as `PsDocument`. Call `XpsDocument.from_file()` to load an XPS document, then convert to the desired output format. ```python from pathlib import Path from aspose.page.xps.document import XpsDocument from aspose.page.ps.output import ImageSaveOptions xps = XpsDocument.from_file("input.xps") pdf_bytes = xps.to_pdf() Path("output.pdf").write_bytes(pdf_bytes) png_bytes = xps.to_image(ImageSaveOptions(format="png", dpi=96)) ``` ### In-Memory Processing All conversion methods return `bytes` objects. Temporary files are never required unless the application explicitly writes them. The `from_bytes()` constructors on both `PsDocument` and `XpsDocument` accept raw bytes as input, so the entire pipeline can stay in memory. ```python from aspose.page.ps.document import PsDocument def convert_ps_in_memory(ps_bytes: bytes) -> bytes: doc = PsDocument.from_bytes(ps_bytes) return doc.to_pdf() ``` ### MCP Server Integration The library includes an optional MCP server that exposes conversion functions as remote tools using FastMCP. The server registers `ps_to_pdf`, `ps_to_image`, `xps_to_pdf`, and `xps_to_image` as callable tools. `McpInput` accepts a file path or base64-encoded bytes; `McpOutput` returns base64 bytes or writes to a path. FastMCP is an optional dependency — the core conversion functionality works without it. The MCP server is useful for making the library callable from AI agent pipelines, microservices, and editors that support MCP tool servers. --- ## Quick Start Install the library with pip: The following example covers the most common use case — converting a PS file to PDF and saving it to disk: ```python from pathlib import Path from aspose.page.ps.document import PsDocument from aspose.page.ps.output import ImageSaveOptions # Convert PS to PDF ps = PsDocument.from_file("document.ps") Path("document.pdf").write_bytes(ps.to_pdf()) # Convert EPS to PNG at 150 DPI eps = PsDocument.from_file("illustration.eps") opts = ImageSaveOptions(format="png", dpi=150) Path("illustration.png").write_bytes(eps.to_image(opts)) # Convert XPS to PDF from aspose.page.xps.document import XpsDocument xps = XpsDocument.from_file("document.xps") Path("document.pdf").write_bytes(xps.to_pdf()) ``` --- ## Supported Formats Aspose.Page FOSS for Python reads PostScript (`.ps`), Encapsulated PostScript (`.eps`), and XML Paper Specification (`.xps`) files. Output formats are PDF (`.pdf`) and raster images (`.png`, `.jpeg`). All conversions are export-only — the library does not write PS, EPS, or XPS. --- ## Open Source & Licensing Aspose.Page FOSS for Python is released under the MIT license. The source code is hosted on GitHub at [github.com/aspose-page-foss/Aspose.Page-FOSS-for-Python](https://github.com/aspose-page-foss/Aspose.Page-FOSS-for-Python). Commercial use is permitted without restriction under the MIT terms. --- ## Getting Started - [Installation Guide](https://docs.aspose.org/page/python/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/page/python/developer-guide/) - [KB Articles](https://kb.aspose.org/page/python/) - [API Reference](https://reference.aspose.org/page/python/) ## Related Resources - [Aspose.Page — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Page for Python — Enterprise Product](https://products.aspose.com/page/python-net/) --- # Common Rendering and Conversion Utilities in Aspose.Page FOSS for Python URL: https://blog.aspose.org/page/python/page-common-in-python/ Aspose.Page FOSS for Python includes a low-level rendering model, PDF output via PdfWriter and PdfMetadata, raster rendering via RasterRenderer, and an XPS document builder. This article covers the shared utilities used across PS, EPS, and XPS pipelines. --- Product: Aspose.Page Platform: python Page Type: index Canonical URL: https://blog.aspose.org/page/python/page-common-in-python/ --- # Common Rendering and Conversion Utilities in Aspose.Page FOSS for Python ## Introduction In addition to the high-level `PsDocument` and `XpsDocument` classes, Aspose.Page FOSS for Python exposes a set of lower-level utilities for building render documents, writing PDF output, and working with XPS packages programmatically. These utilities are used internally by the high-level classes and can also be used directly when you need precise control over the output. This article covers `RenderModelBuilder`, `PdfWriter`, `PdfMetadata`, `RasterRenderer`, and `XpsDocumentBuilder` — the common components shared across PS, EPS, and XPS pipelines. --- ## Building a Render Document `RenderModelBuilder` constructs a `RenderDocument` incrementally by calling page lifecycle methods. Start a page with `begin_page()`, add drawing commands, then call `end_page()`. Call `document()` to retrieve the completed `RenderDocument`. ```python from aspose.page.render.model import RenderModelBuilder builder = RenderModelBuilder() builder.begin_page(595, 842) # add paths, text, images here builder.end_page() doc = builder.document() ``` Available drawing methods include `add_path()`, `add_text()`, `add_image()`, `clip()`, `save_state()`, and `restore_state()`. Call `set_default_page_size()` before `begin_page()` to establish a default size that applies to all subsequent pages. --- ## Writing a Render Document to PDF `PdfWriter` accepts a `PdfMetadata` instance and serializes a `RenderDocument` to PDF 1.4 bytes. Pass a `PdfMetadata` object with `title`, `creator`, `producer`, `creation_date`, `mod_date`, and `trapped` fields, then call `write(doc)` to produce the output. ```python from aspose.page.render.model import RenderModelBuilder from aspose.page.pdf.writer import PdfWriter from aspose.page.pdf.metadata import PdfMetadata from pathlib import Path builder = RenderModelBuilder() builder.begin_page(595, 842) builder.end_page() doc = builder.document() metadata = PdfMetadata( title="My Document", creator="My App", producer="Aspose.Page FOSS for Python", creation_date="D:20260609000000", mod_date="D:20260609000000", trapped=False, ) writer = PdfWriter(metadata) pdf_bytes = writer.write(doc) Path("output.pdf").write_bytes(pdf_bytes) ``` --- ## Raster Rendering `RasterRenderer` renders a `RenderDocument` to a `RasterSurface` — an in-memory RGBA pixel buffer. The `RasterSurface` provides `get_pixel()` and `set_pixel()` for direct pixel access, along with `width` and `height` properties. This is the underlying mechanism used by `to_image()` on both `PsDocument` and `XpsDocument` when producing PNG or JPEG output. ```python from aspose.page.render.model import RenderModelBuilder from aspose.page.image.raster_renderer import RasterRenderer builder = RenderModelBuilder() builder.begin_page(400, 300) builder.end_page() doc = builder.document() renderer = RasterRenderer() surface = renderer.render(doc, page_index=0) print(f"Surface size: {surface.width}x{surface.height}") ``` --- ## Building XPS Documents Programmatically `XpsDocumentBuilder` provides a high-level API for constructing XPS packages with custom pages and metadata. Use `create_page()` to add pages, then call `to_document()` to obtain an `XpsDocument` that can be further exported to PDF or raster images. ```python from aspose.page.xps.document import XpsDocument xps = XpsDocument.create("My XPS Document") page = xps.add_page(595, 842) ``` --- ## Getting Started - [Installation Guide](https://docs.aspose.org/page/python/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/page/python/developer-guide/) - [KB Articles](https://kb.aspose.org/page/python/) - [API Reference](https://reference.aspose.org/page/python/) ## Related Resources - [Aspose.Page — Enterprise Blog](https://blog.aspose.com/) --- # Working with PS and EPS Files in Python URL: https://blog.aspose.org/page/python/page-ps-python/ Aspose.Page FOSS for Python provides PsDocument for loading PostScript and EPS files and exporting them to PDF byte arrays or raster images. No Ghostscript required. --- Product: Aspose.Page Platform: python Page Type: index Canonical URL: https://blog.aspose.org/page/python/page-ps-python/ --- # Working with PS and EPS Files in Python ## Introduction PostScript (PS) and Encapsulated PostScript (EPS) are vector document formats used in print workflows, legacy publishing systems, and graphics pipelines. Aspose.Page FOSS for Python provides `PsDocument` — a single class that handles both `.ps` and `.eps` files — with methods to export them to PDF or raster images directly from Python code. The library requires no Ghostscript installation, no Adobe runtime, and no native system dependencies. It runs on Windows, Linux, and macOS. Install it with pip and use it immediately in any Python 3.10+ environment. --- ## Loading PS and EPS Files `PsDocument` exposes two class methods for loading a document. `from_file()` reads from a file path; `from_bytes()` accepts raw bytes from a stream or upload. ```python from aspose.page.ps.document import PsDocument # Load from file path ps = PsDocument.from_file("document.ps") eps = PsDocument.from_file("illustration.eps") # Load from bytes (network stream, upload, etc.) with open("document.ps", "rb") as f: data = f.read() ps_from_bytes = PsDocument.from_bytes(data) ``` The `is_eps` property returns `True` if the document is an EPS file, which is useful when processing a mixed batch of PS and EPS files through the same code path. --- ## Exporting to PDF Call `to_pdf()` on a loaded `PsDocument` to obtain the output as a `bytes` object. The result is a valid PDF byte stream that can be written to disk, stored in a database, or returned from an HTTP endpoint. ```python from pathlib import Path from aspose.page.ps.document import PsDocument ps = PsDocument.from_file("input.ps") pdf_bytes = ps.to_pdf() Path("output.pdf").write_bytes(pdf_bytes) ``` No options object is required for a default PDF export. The `to_pdf()` method accepts an optional options parameter for advanced use cases. --- ## Exporting to Raster Images To render a PS or EPS document to a raster image, pass an `ImageSaveOptions` instance to `to_image()`. Set `format` to `"png"` or `"jpeg"` and `dpi` to control the output resolution. The method returns a `bytes` object containing the encoded image. ```python from pathlib import Path from aspose.page.ps.document import PsDocument from aspose.page.ps.output import ImageSaveOptions eps = PsDocument.from_file("illustration.eps") opts = ImageSaveOptions(format="png", dpi=150) png_bytes = eps.to_image(opts) Path("output.png").write_bytes(png_bytes) ``` For JPEG output, change `format="jpeg"`. The `dpi` property defaults to 96 when not set. --- ## Reading EPS Metadata `PsDocument` exposes a `dsc` property that returns a `DscMetadata` instance when DSC comments are present in the file. `DscMetadata` provides structured access to bounding box coordinates, page size, orientation, title, and creator fields parsed from the EPS header. ```python from aspose.page.ps.document import PsDocument eps = PsDocument.from_file("illustration.eps") dsc = eps.dsc if dsc is not None: print("Title:", dsc.title) print("Bounding box:", dsc.bounding_box) print("HiRes bounding box:", dsc.hires_bounding_box) ``` --- ## Batch Conversion Because all conversion methods return `bytes` and accept file paths or raw bytes as input, batch processing is direct to implement with standard Python loops or `concurrent.futures`. ```python from pathlib import Path from aspose.page.ps.document import PsDocument input_dir = Path("ps-files") output_dir = Path("pdf-output") output_dir.mkdir(exist_ok=True) for ps_file in input_dir.glob("*.ps"): doc = PsDocument.from_file(str(ps_file)) out_path = output_dir / ps_file.with_suffix(".pdf").name out_path.write_bytes(doc.to_pdf()) print("Converted:", ps_file.name) ``` The same pattern applies to EPS files by changing the glob pattern to `"*.eps"`. --- ## Getting Started - [Installation Guide](https://docs.aspose.org/page/python/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/page/python/developer-guide/) - [KB Articles](https://kb.aspose.org/page/python/) - [API Reference](https://reference.aspose.org/page/python/) ## Related Resources - [Aspose.Page — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.PDF FOSS for C++ URL: https://blog.aspose.org/pdf/cpp/introducing-pdf-foss-cpp/ Aspose.PDF FOSS for C++ is a free, MIT-licensed C++20 library for opening, creating, and modifying PDF documents. It covers page access, text extraction, raster rendering, encryption, annotations, and AcroForm fields through the Document class and a set of device classes, with no proprietary runtime dependencies. --- Product: Aspose.PDF Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/pdf/cpp/introducing-pdf-foss-cpp/ --- # Introducing Aspose.PDF FOSS for C++ ## Introduction Aspose.PDF FOSS for C++ is a new open-source library for working with PDF documents from C++20 code. It is released under the MIT license and carries no runtime dependency beyond the C++ standard library — the BMP, JPEG, and TIFF encoders, the page rasteriser, and the PDF parser are implemented internally, so there is no link to a commercial PDF engine, an external image codec, or a third-party cryptography library. The library is organized around the `Aspose::Pdf::Document` class, which loads a PDF from a file path and exposes its contents through `Document.Pages()`, a `PageCollection` of individual `Page` objects. From there, the API covers text extraction, page rasterisation, document encryption, annotations, and AcroForm fields — the operations needed to read, inspect, and modify existing PDF files, or assemble new ones from scratch. This release is for developers who need PDF processing inside a C++ codebase without adding a commercial license or a third-party dependency chain: document pipelines, content-extraction services, PDF-to-image conversion tools, and applications that need to encrypt or read back form data as part of a larger build. --- ## What's Included ### Document Loading and Page Access Opening an existing PDF is a single constructor call. `Document` parses the file and exposes its pages through `Pages()`, which returns a `PageCollection` supporting 1-based indexing, `Count()`, and `Add()`/`Insert()`/`Delete()` for restructuring page order. ```cpp #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); std::cout #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); Aspose::Pdf::Text::TextAbsorber absorber; absorber.Visit(doc); std::cout #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); Aspose::Pdf::Devices::BmpDevice bmp(Aspose::Pdf::Devices::Resolution(150)); std::ofstream out("page1.bmp", std::ios::binary); bmp.Process(doc.Pages()[1], out); } ``` ### Encryption `Document.Encrypt()` protects a document with a user password, an owner password, a permission value, and a `CryptoAlgorithm` selection. The enum covers RC4-40 (`RC4x40`), RC4-128 (`RC4x128`), AES-128 (`AESx128`), and AES-256 (`AESx256`). `Document.Decrypt()` reverses the operation, and `IsEncrypted()` reports whether a document is currently encrypted. ```cpp #include int main() { Aspose::Pdf::Document doc("input.pdf"); doc.Encrypt("user-password", "owner-password", Aspose::Pdf::Permissions::PrintDocument, Aspose::Pdf::CryptoAlgorithm::AESx256); doc.Save("encrypted.pdf"); } ``` ### Annotations Each `Page` exposes an `AnnotationCollection` through `Annotations()`. A `TextAnnotation` is constructed against the owning document, positioned with a `Rectangle`, and added to the page's collection with `Add()`. ```cpp #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); Aspose::Pdf::Annotations::TextAnnotation note(doc); note.Rect(Aspose::Pdf::Rectangle(100.0, 700.0, 200.0, 720.0, false)); note.Contents("Reviewed - see section 2"); doc.Pages()[1].Annotations().Add(note); doc.Save("annotated.pdf"); } ``` ### AcroForm Fields `Document.Form()` returns the document's `Form`, which exposes existing fields through `Fields()` as a `std::vector`. Each `Field` reports its name and current value through `PartialName()` and `Value()`, and `Form.Flatten()` bakes every field's appearance into the page content, removing interactivity. ```cpp #include #include int main() { Aspose::Pdf::Document doc("form.pdf"); auto& form = doc.Form(); std::cout PartialName() Value() #include #include #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); std::cout << "Pages: " << doc.Pages().Count() << "\n"; Aspose::Pdf::Text::TextAbsorber absorber; absorber.Visit(doc); std::cout << absorber.Text() << "\n"; Aspose::Pdf::Devices::BmpDevice bmp(Aspose::Pdf::Devices::Resolution(150)); std::ofstream out("page1.bmp", std::ios::binary); bmp.Process(doc.Pages()[1], out); } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | BMP | .bmp | — | ✓ | | JPEG | .jpg | — | ✓ | | TIFF | .tiff | — | ✓ | | Text | .txt | — | ✓ | | SVG | .svg | ✓ | — | BMP, JPEG, and TIFF are page-rendering outputs produced by their respective device classes. Text is extracted from a PDF via `TextAbsorber`. SVG is imported as vector content through the library's SVG load path. --- ## Open Source & Licensing Aspose.PDF FOSS for C++ is distributed under the MIT license, with the full source available at [github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp](https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp). The license permits commercial use, modification, and redistribution without a separate agreement. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/cpp/) - [API Reference](https://reference.aspose.org/pdf/cpp/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # PDF Annotations in C++ - Text Notes, Links, Highlights, and Stamps URL: https://blog.aspose.org/pdf/cpp/pdf-annotations-in-cpp/ Aspose.PDF FOSS for C++ exposes an Annotation class hierarchy for adding, reading, and modifying PDF annotations — text notes, links, text markup, shapes, and stamps — through classes such as TextAnnotation, LinkAnnotation, HighlightAnnotation, and StampAnnotation, all stored per page in an AnnotationCollection. --- Product: Aspose.PDF Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/pdf/cpp/pdf-annotations-in-cpp/ --- # PDF Annotations in C++ - Text Notes, Links, Highlights, and Stamps ## Introduction PDF annotations cover a wide range of interactive and visual elements layered on top of page content: sticky text notes, hyperlinks, highlighted or struck-through text, geometric shapes, ink strokes, file attachments, and approval stamps. Aspose.PDF FOSS for C++ represents every one of these as a concrete subclass of `Annotation`, so code that walks a page's annotations can work generically against the base class while still reaching subtype-specific members — such as `Icon()` on a `TextAnnotation` or `Action()` on a `LinkAnnotation` — when needed. The library's `Annotations::AnnotationType` enum enumerates the subtypes it recognizes: `Text`, `Link`, `FreeText`, `Line`, `Square`, `Circle`, `Polygon`, `PolyLine`, `Highlight`, `Underline`, `Squiggly`, `StrikeOut`, `Stamp`, `Caret`, `Ink`, `Popup`, `FileAttachment`, `Sound`, `Movie`, `Widget`, `Screen`, `PrinterMark`, `Watermark`, `Redaction`, `RichMedia`, and several others. Each value maps to a concrete class — `CircleAnnotation`, `SquareAnnotation`, `PolygonAnnotation`, `PolylineAnnotation`, and `LineAnnotation` for shape markup; `FreeTextAnnotation` and `InkAnnotation` for free-form text and drawn strokes; `FileAttachmentAnnotation`, `SoundAnnotation`, `MovieAnnotation`, `ScreenAnnotation`, and `RichMediaAnnotation` for embedded content; and `WidgetAnnotation` for AcroForm field appearances. This post covers the `Annotation` and `AnnotationCollection` base API, adding text notes and links, detecting annotation types when loading an existing document, and reading or updating markup metadata and stamps. Aspose.PDF FOSS for C++ is a C++20 library with no runtime dependencies beyond the standard library; headers are included directly from the `aspose/pdf/annotations/` directory and the library builds as a CMake target. --- ## What's Included ### Annotation and AnnotationCollection `Annotation` is the base class for every annotation subtype. It exposes shared properties: `Rect()` / `Rect(value)` for the annotation's bounding rectangle, `Contents()` for the associated text, `Name()`, `Color()`, `Flags()` (an `AnnotationFlags` bitmask — `Print`, `Hidden`, `Invisible`, `NoZoom`, `ReadOnly`, and others), `Border()`, `Width()` / `Height()`, `AnnotationType()`, and `PageIndex()`. `AnnotationCollection` holds the annotations on a single page and is reached through `Page.Annotations()`. ```cpp #include #include #include using namespace Aspose::Pdf; using namespace Aspose::Pdf::Annotations; Document doc("reviewed.pdf"); AnnotationCollection& annots = doc.Pages()[1].Annotations(); std::cout #include using namespace Aspose::Pdf; using namespace Aspose::Pdf::Annotations; Document doc("input.pdf"); TextAnnotation note{doc}; note.Rect(Rectangle{100.0, 700.0, 200.0, 720.0, false}); note.Contents("Reviewed by QA"); note.Icon(TextIcon::Comment); note.Open(true); doc.Pages()[1].Annotations().Add(note); doc.Save("annotated.pdf"); ``` ### Links and Actions with LinkAnnotation `LinkAnnotation` attaches a clickable region to a page. It is constructed from the owning `Page` and a `Rectangle`, and its behavior is set with `Action(value)` — any `PdfAction` subclass, including `NamedAction` (predefined navigation such as `PredefinedAction::LastPage`), `GoToAction`, `GoToURIAction`, or `JavascriptAction`. `Destination()` reads the link's `IAppointment` target, and `Highlighting()` / `Highlighting(value)` sets the `HighlightingMode` (`None`, `Invert`, `Outline`, `Push`, `Toggle`) applied when the link is activated. ```cpp #include #include #include using namespace Aspose::Pdf; using namespace Aspose::Pdf::Annotations; Document doc; Page page = doc.Pages().Add(); LinkAnnotation link{page, Rectangle{0.0, 0.0, 100.0, 20.0, false}}; link.Action(NamedAction{PredefinedAction::LastPage}); link.Highlighting(HighlightingMode::Push); page.Annotations().Add(link); ``` ### Detecting Annotation Types on Load When a document is opened, existing annotations are already populated in each page's `AnnotationCollection`, and `AnnotationType()` identifies which concrete subtype each entry represents. This lets calling code branch on the enum value without knowing in advance which annotation types a given PDF contains. ```cpp #include #include #include using namespace Aspose::Pdf; using namespace Aspose::Pdf::Annotations; Document doc("mixed-annotations.pdf"); auto& annots = doc.Pages()[1].Annotations(); for (int i = 0; i #include using namespace Aspose::Pdf::Annotations; for (int i = 0; i (&annots[i])) { markup->Title("QA Reviewer"); markup->Subject("Layout issue"); markup->Opacity(0.6); } } ``` ### Stamp Annotations with StampAnnotation `StampAnnotation` places a predefined or custom stamp on a page. `Icon()` / `Icon(value)` selects a `StampIcon` value — `Approved`, `Draft`, `Confidential`, `Final`, `Expired`, `NotApproved`, `ForComment`, `TopSecret`, and others — and `Image()` / `Image(value)` supplies raw image bytes for a custom stamp appearance instead of a built-in icon. ```cpp #include #include using namespace Aspose::Pdf::Annotations; for (int i = 0; i (&annots[i])) { stamp->Icon(StampIcon::Approved); } } ``` --- ## Quick Start Add the library as a CMake subdirectory and link against the `aspose_pdf_foss` target: ```cmake add_subdirectory(aspose.pdf-foss-for-cpp) target_link_libraries(your_app PRIVATE aspose_pdf_foss) ``` Open a document, add a text note, and read the annotation count back: ```cpp #include #include #include using namespace Aspose::Pdf; using namespace Aspose::Pdf::Annotations; int main() { Document doc("input.pdf"); TextAnnotation note{doc}; note.Rect(Rectangle{100.0, 700.0, 200.0, 720.0, false}); note.Contents("Reviewed by QA"); note.Icon(TextIcon::Comment); doc.Pages()[1].Annotations().Add(note); doc.Save("annotated.pdf"); std::cout << "Annotations on page 1: " << doc.Pages()[1].Annotations().Count() << "\n"; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | BMP | .bmp | — | ✓ | | JPEG | .jpg | — | ✓ | | TIFF | .tiff | — | ✓ | | Text | .txt | — | ✓ | | SVG | .svg | ✓ | — | Format support applies to page rendering and load options at the document level; these entries reflect confirmed export (`BmpDevice`, `JpegDevice`, `TiffDevice`, `TextDevice`) and import (`SvgLoadOptions`) paths rather than annotation-specific serialization. --- ## Open Source & Licensing Aspose.PDF FOSS for C++ is released under the MIT license. Source code is available at `https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp`, and the library can be used in commercial and open-source projects without licensing fees. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/cpp/) - [API Reference](https://reference.aspose.org/pdf/cpp/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.PDF FOSS for C++: Key Features for PDF Processing URL: https://blog.aspose.org/pdf/cpp/pdf-core-features-cpp/ Aspose.PDF FOSS for C++ is an open-source, dependency-free C++20 library for creating, editing, rendering, and securing PDF documents. It covers document and page management, text extraction with TextAbsorber, rendering to BMP/JPEG/TIFF images, and RC4/AES encryption through Document.Encrypt(). MIT licensed with no runtime dependencies beyond the C++ standard library. --- Product: Aspose.PDF Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/pdf/cpp/pdf-core-features-cpp/ --- # Aspose.PDF FOSS for C++: Key Features for PDF Processing ## Introduction Aspose.PDF FOSS for C++ is an open-source C++20 library for working with PDF documents. The API surface spans document and page management, text extraction, raster rendering, encryption, annotations, and interactive AcroForm fields — the operations most commonly needed when a C++ application has to create, inspect, or transform PDF files without depending on an external PDF engine or a commercial SDK. The library links against nothing but the C++ standard library. Internal components such as the BMP, JPEG, and TIFF raster encoders and the page rasterizer are implemented from scratch inside the project, so there is no dependency on a system PDF renderer, a commercial PDF component, or any third-party image codec. This keeps the dependency footprint at zero beyond a C++20-conformant compiler and standard library. Aspose.PDF FOSS for C++ is released under the MIT license. This post walks through the main feature areas exposed by the `Document` class and its supporting types, followed by a Quick Start example and the currently confirmed format support. --- ## Key Features ### Document and Page Management The `Document` class is the entry point for opening, inspecting, and saving PDF files. Pages are accessed through `Document.Pages()`, which returns a `PageCollection` supporting `Count()`, `Add()`, `Insert(pageNumber)`, and `Delete(pageNumber)`. Document-level metadata is read and updated through `Document.Info()` (a `DocumentInfo` instance) or set directly with `Document.SetTitle()`. ```cpp #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); std::cout #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); // Extract all text from the document Aspose::Pdf::Text::TextAbsorber absorber; absorber.Visit(doc); std::cout #include #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto page = doc.Pages()[1]; Aspose::Pdf::Devices::PngDevice png(Aspose::Pdf::Devices::Resolution(150)); std::ofstream pngOut("page1.png", std::ios::binary); png.Process(page, pngOut); Aspose::Pdf::Devices::BmpDevice bmp(Aspose::Pdf::Devices::Resolution(150)); std::ofstream bmpOut("page1.bmp", std::ios::binary); bmp.Process(page, bmpOut); } ``` `JpegDevice` follows the same `Process(page, output)` pattern for JPEG output. `TiffDevice` additionally supports multi-page output in a single call through `Process(document, fromPage, toPage, output)`, and exposes `RenderingOptions()` for controlling how form fields are rendered into the raster output. ### Encryption and Access Permissions `Document.Encrypt()` protects a document with a user and owner password, selecting the cipher through the `CryptoAlgorithm` enum: `RC4x40`, `RC4x128`, `AESx128`, or `AESx256`. Granted permissions are described with the `Permissions` type, whose flag values include `PrintDocument`, `ModifyContent`, `ExtractContent`, `ModifyTextAnnotations`, `FillForm`, `ExtractContentWithDisabilities`, `AssembleDocument`, and `PrintingQuality`. ```cpp #include int main() { Aspose::Pdf::Document doc("input.pdf"); doc.Encrypt("user-password", "owner-password", Aspose::Pdf::Permissions(), Aspose::Pdf::CryptoAlgorithm::AESx256); doc.Save("encrypted.pdf"); } ``` An already-open encrypted document is decrypted in place with `Document.Decrypt()`. `Document.IsEncrypted()` reports whether a loaded document currently carries an encryption dictionary. ### Annotations Page-level annotations — text notes, shapes, and markup — are reached through `Page.Annotations()`, which returns an `AnnotationCollection`. Individual entries expose shared properties such as `Contents()`, `Rect()`, `Color()`, `Border()`, and `AnnotationType()`, and can be removed from the page or flattened into static content. ```cpp #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& annotations = doc.Pages()[1].Annotations(); std::cout (annotations.Count()); ++i) { std::cout 0) { annotations.Delete(annotations[0]); } doc.Save("output.pdf"); } ``` Any single `Annotation` can also be converted to static page content directly with its own `Flatten()` method, independent of the form-flattening workflow described below. ### Interactive Forms AcroForm fields on a document are managed through `Document.Form()`, which returns a `Form` instance supporting `Count()`, `HasField(fieldName)`, `Delete(fieldName)`, and `Flatten()`. New fields are attached with `Form.Add(field, pageNumber)`, where `field` is a concrete `Field` subtype such as `TextBoxField`, `CheckboxField`, `ChoiceField`, or `ButtonField`. ```cpp #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& form = doc.Form(); std::cout #include #include #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); std::cout << "Pages: " << doc.Pages().Count() << "\n"; Aspose::Pdf::Text::TextAbsorber absorber; absorber.Visit(doc); std::cout << absorber.Text() << "\n"; Aspose::Pdf::Devices::PngDevice png(Aspose::Pdf::Devices::Resolution(150)); std::ofstream out("page1.png", std::ios::binary); png.Process(doc.Pages()[1], out); } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | BMP | bmp | — | ✓ | | JPEG | jpeg | — | ✓ | | TIFF | tiff | — | ✓ | | Text | txt | — | ✓ | | SVG | svg | ✓ | — | --- ## Open Source & Licensing Aspose.PDF FOSS for C++ is released under the MIT license, permitting commercial use, modification, and redistribution without royalties. The source is available at [github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp](https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp). Commercial use is permitted under the MIT license terms. If your project requires enterprise-grade support, extended format coverage, or cloud integration, the [Aspose.PDF — Enterprise Product Family](https://products.aspose.com/pdf/) is a separate commercial offering. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/cpp/) - [API Reference](https://reference.aspose.org/pdf/cpp/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Document Management in Aspose.PDF FOSS for C++: Metadata, Outlines, and Attachments URL: https://blog.aspose.org/pdf/cpp/pdf-document-management-in-cpp/ Aspose.PDF FOSS for C++ organizes document-level state — the /Info dictionary, XMP metadata, outlines (bookmarks), named destinations, embedded files, and page labels — around the Document class and a set of dedicated collection types. This post covers the DocumentInfo, Metadata, Outlines, NamedDestinationCollection, EmbeddedFileCollection, and PageLabelCollection APIs with working C++ examples. --- Product: Aspose.PDF Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/pdf/cpp/pdf-document-management-in-cpp/ --- # Document Management in Aspose.PDF FOSS for C++: Metadata, Outlines, and Attachments ## Introduction This guide shows how to read and update document-level state in Aspose.PDF FOSS for C++ — the parts of a PDF that describe the document itself rather than what is drawn on its pages. Aspose.PDF FOSS for C++ centers on the `Aspose::Pdf::Document` class, which loads an existing PDF from a file path and exposes it for both content editing and document-level bookkeeping. Document-level bookkeeping covers the `/Info` dictionary, the XMP metadata stream, the bookmark (outline) tree shown in a viewer's navigation panel, named destinations used by internal links, file attachments embedded in the PDF, and the custom page-numbering sequences a document can define. This post walks through the API surface for each of these areas: `DocumentInfo` for the classic `/Info` dictionary fields (title, author, creator, subject, keywords), `Metadata` for the XMP metadata stream, `Outlines` and `OutlineItemCollection` for the bookmark tree, `NamedDestinationCollection` for named links, `EmbeddedFileCollection` and `FileSpecification` for attachments, and `PageLabelCollection` for per-range page numbering. Each section pairs the relevant class with a working example built from a loaded `Document` object. Aspose.PDF FOSS for C++ is released under the MIT license and links against nothing but the C++ standard library, so every operation described here runs without a proprietary PDF engine or third-party dependency. The library builds as a static target (`aspose_pdf_foss`) added via CMake. --- ## What's Included ### The `/Info` Dictionary — `DocumentInfo` `Document.Info()` returns a `DocumentInfo` reference bound to the PDF's `/Info` dictionary. It has typed accessors for the standard fields — `Title()`, `Author()`, `Creator()`, `Subject()`, `Keywords()`, `Producer()`, and `Trapped()` — each with a matching setter, plus a generic `Add(key, value)` / `Remove(key)` pair for custom keys and `IsPredefinedKey(key)` to check whether a key name is one of the standard fields. `Document.SetTitle()` is a shortcut that writes the title directly on the document. ```cpp #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& info = doc.Info(); std::cout #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& metadata = doc.Metadata(); metadata.RegisterNamespaceUri("myapp", "http://example.com/myapp/1.0/"); metadata.Add("myapp:BatchId", "2026-07-run-42"); std::cout #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& outlines = doc.Outlines(); std::cout 0) { auto& first = outlines.First(); std::cout #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& destinations = doc.NamedDestinations(); std::cout #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& files = doc.EmbeddedFiles(); std::cout #include #include #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& labels = doc.PageLabels(); for (int pageIndex : labels.GetPages()) { auto label = labels.GetLabel(pageIndex); std::cout #include int main() { Aspose::Pdf::Document doc("input.pdf"); auto& info = doc.Info(); std::cout << "Title: " << info.Title() << "\n"; std::cout << "Author: " << info.Author() << "\n"; doc.SetTitle("Updated Report Title"); info.Author("Report Generator"); info.Add("Generated-By", "Aspose.PDF FOSS for C++"); doc.Save("output.pdf"); return 0; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | BMP | .bmp | — | ✓ | | JPEG | .jpg | — | ✓ | | TIFF | .tiff | — | ✓ | | Text | .txt | — | ✓ | | SVG | .svg | ✓ | — | BMP, JPEG, and TIFF are page-rendering outputs produced by their respective device classes, and text is extracted via `TextAbsorber`. SVG is imported as vector content through the library's SVG load path. None of the document-management types covered above are format converters — they read and write PDF structure only. --- ## Open Source & Licensing Aspose.PDF FOSS for C++ is distributed under the MIT license, with the full source available at [github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp](https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp). The license permits commercial use, modification, and redistribution without a separate agreement. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/cpp/) - [API Reference](https://reference.aspose.org/pdf/cpp/) - [GitHub Repository](https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Drawing Vector Graphics on a PDF Page with Aspose.PDF FOSS for C++ URL: https://blog.aspose.org/pdf/cpp/pdf-graphics-in-cpp/ Aspose.PDF FOSS for C++ includes a vector-graphics API for drawing free-form shapes directly onto a PDF page through the Graph container and the Circle, Ellipse, and Line shape classes, with stroke and fill styling through GraphInfo and BorderInfo. --- Product: Aspose.PDF Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/pdf/cpp/pdf-graphics-in-cpp/ --- # Drawing Vector Graphics on a PDF Page with Aspose.PDF FOSS for C++ ## Introduction Aspose.PDF FOSS for C++ includes a small vector-graphics API for building free-form shapes directly on a PDF page. This is separate from the library's raster-rendering path — `BmpDevice`, `JpegDevice`, and `TiffDevice`, which convert existing page content to image formats — and instead lets a program construct new geometry (circles, ellipses, and lines) on a page as the document is generated. The API centers on a `Graph`, a container that holds a set of `Shape` objects and is placed on a page in the same way as other page content, through `Page.Paragraphs()`. Three concrete shapes derive from the abstract `Shape` base: `Circle`, `Ellipse`, and `Line`, each expressing its geometry through a small set of numeric properties rather than a shared point or rectangle type. Stroke width, color, fill, and dash pattern are set per shape through `GraphInfo`, and the `Graph` container itself carries a `BorderInfo` for framing the whole container. This is a narrow area of the library — five classes covering shape geometry and styling — intended for programs that need to draw simple geometric content (borders, markers, connecting lines, highlight circles) on a page without building a full vector-drawing layer or falling back to image compositing. --- ## What's Included ### The Graph Container and Adding Shapes to a Page `Graph` holds the shapes drawn on a page. Its own properties — `Left()`, `Top()`, `Width()`, `Height()`, and `IsChangePosition()` — position and size the container on the page, and `Shapes()` returns the vector of `Shape` pointers it holds. Shapes are added by constructing them, setting their properties, and appending them to that vector; the `Graph` itself is added to the page through `Page.Paragraphs().Add()`. ```cpp #include #include #include using namespace Aspose::Pdf; int main() { Document doc; Page page = doc.Pages().Add(); auto graph = std::make_shared(); graph->Left(50.0); graph->Top(50.0); graph->Width(400.0); graph->Height(400.0); auto circle = std::make_unique(); circle->PosX(200.0); circle->PosY(200.0); circle->Radius(75.0); graph->Shapes().push_back(std::move(circle)); page.Paragraphs().Add(graph); doc.Save("graph.pdf"); } ``` ### Drawing Circles and Ellipses `Circle` and `Ellipse` each describe their geometry with plain numeric properties instead of a shared point or rectangle type. `Circle` exposes `PosX()`, `PosY()`, and `Radius()`; `Ellipse` exposes `Left()`, `Bottom()`, `Width()`, and `Height()`, describing a bounding box in the same style `Graph` itself uses for positioning. Both override `CheckBounds(containerWidth, containerHeight)`, inherited from `Shape`, which reports whether the shape's current geometry fits inside a container of the given size. ```cpp #include #include using namespace Aspose::Pdf; Circle circle; circle.PosX(150.0); circle.PosY(150.0); circle.Radius(50.0); bool circleFits = circle.CheckBounds(400.0, 400.0); Ellipse ellipse; ellipse.Left(20.0); ellipse.Bottom(20.0); ellipse.Width(120.0); ellipse.Height(60.0); bool ellipseFits = ellipse.CheckBounds(400.0, 400.0); ``` ### Drawing Lines `Line` stores its geometry differently from `Circle` and `Ellipse`: `PositionArray()` returns a flat `std::vector` of coordinates — an x, y pair for each point the line passes through — rather than a set of named properties. A two-point segment is set with four values: start x, start y, end x, end y. Like the other shapes, `Line` overrides `CheckBounds(containerWidth, containerHeight)` from `Shape`. ```cpp #include using namespace Aspose::Pdf; Line line; line.PositionArray({50.0f, 50.0f, 350.0f, 350.0f}); bool lineFits = line.CheckBounds(400.0, 400.0); ``` ### Styling Shapes with GraphInfo and BorderInfo Each shape's stroke and fill come from a `GraphInfo`, read and set through `Shape.GraphInfo()` / `GraphInfo(value)`. `GraphInfo` exposes stroke width (`LineWidth()`), stroke and fill color (`Color()`, `FillColor()`), a dash pattern (`DashArray()`, `DashPhase()`), a doubled-line flag (`IsDoubled()`), and skew/scale/rotation properties (`SkewAngleX()`/`SkewAngleY()`, `ScalingRateX()`/`ScalingRateY()`, `RotationAngle()`). The `Graph` container also carries a `BorderInfo`, set through `Border()`, which holds one `GraphInfo` per edge — `Left()`, `Right()`, `Top()`, `Bottom()` — plus a `RoundedBorderRadius()` for rounding the container's own border. ```cpp #include #include #include using namespace Aspose::Pdf; GraphInfo stroke; stroke.LineWidth(2.0f); stroke.Color(Color::FromRgb(1.0, 0.0, 0.0)); stroke.FillColor(Color::FromRgb(1.0, 0.9, 0.9)); stroke.DashArray({4, 2}); BorderInfo border{BorderSide::All, 1.5f, Color::Black()}; border.RoundedBorderRadius(6.0); ``` --- ## Quick Start Add the library as a CMake subdirectory and link against the `aspose_pdf_foss` target: ```cmake add_subdirectory(aspose.pdf-foss-for-cpp) target_link_libraries(your_app PRIVATE aspose_pdf_foss) ``` Create a document, add a page, draw a circle inside a `Graph` container, and save the result: ```cpp #include #include #include using namespace Aspose::Pdf; int main() { Document doc; Page page = doc.Pages().Add(); auto graph = std::make_shared(); graph->Left(50.0); graph->Top(50.0); graph->Width(300.0); graph->Height(300.0); auto circle = std::make_unique(); circle->PosX(150.0); circle->PosY(150.0); circle->Radius(100.0); graph->Shapes().push_back(std::move(circle)); page.Paragraphs().Add(graph); doc.Save("circle.pdf"); } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | BMP | .bmp | — | ✓ | | JPEG | .jpg | — | ✓ | | TIFF | .tiff | — | ✓ | | Text | .txt | — | ✓ | | SVG | .svg | ✓ | — | These formats apply to the library as a whole — page rasterization (BMP, JPEG, TIFF), text extraction (Text), and SVG import — rather than to the vector-graphics classes specifically. `Graph`, `Shape`, `Circle`, `Ellipse`, and `Line` draw directly into the PDF page content and are not tied to a file format of their own. --- ## Open Source & Licensing Aspose.PDF FOSS for C++ is distributed under the MIT license, with the full source available at [github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp](https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp). The license permits commercial use, modification, and redistribution without a separate agreement. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/cpp/) - [API Reference](https://reference.aspose.org/pdf/cpp/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.PDF FOSS for Java URL: https://blog.aspose.org/pdf/java/ --- Product: Aspose.PDF Platform: java Page Type: index Canonical URL: https://blog.aspose.org/pdf/java/ --- # Aspose.PDF FOSS for Java Articles and tutorials for Aspose.PDF FOSS for Java. ## Related Topics - [Introducing Aspose.PDF FOSS for Java](https://blog.aspose.org/pdf/java/java-pdf-create-edit-library/) - [Core Features of Aspose.PDF FOSS for Java](https://blog.aspose.org/pdf/java/pdf-core-features-java/) - [Working with PDF Facades in Java](https://blog.aspose.org/pdf/java/pdf-facades-in-java/) - [PDF Document Manipulation with Aspose.PDF FOSS for Java](https://blog.aspose.org/pdf/java/pdf-page-editing-java/) --- # Introducing Aspose.PDF FOSS for Java URL: https://blog.aspose.org/pdf/java/java-pdf-create-edit-library/ Aspose.PDF FOSS for Java is a free, MIT-licensed Java library for creating and working with PDF documents. It exposes 527 classes covering annotations, form fields, page manipulation, PDF/A compliance, and AES encryption. --- Product: Aspose.PDF Platform: java Page Type: index Canonical URL: https://blog.aspose.org/pdf/java/java-pdf-create-edit-library/ --- # Introducing Aspose.PDF FOSS for Java ## Introduction Aspose.PDF FOSS for Java is an MIT-licensed Java library for creating and manipulating PDF documents. It is available on GitHub under the MIT license and requires no API key or commercial agreement. The library exposes 527 classes covering the complete PDF specification from document structure to annotations, interactive forms, page rendering, and cryptographic operations. The library is built around the `Document` class, which is the central entry point for all PDF operations. Creating a new document, accessing pages via `PageCollection`, reading metadata through `DocumentInfo`, or navigating the catalog via `getCatalog()` and `getTrailer()` — all begin with a `Document` instance. ## Quick Start Add the Maven dependency to your `pom.xml`: The library organises all public API classes under three packages. Add these package declarations to any Java source file that uses the API: ```java // Core API — Document, Page, Annotation, Form, etc. import org.aspose.pdf.*; // Annotation subclasses import org.aspose.pdf.annotations.*; // Facade classes — PdfFileEditor, PdfAnnotationEditor, etc. import org.aspose.pdf.facades.*; ``` Aspose.PDF FOSS for Java requires Java 11 or later. The source code and issue tracker are available at `https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java`. ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/java/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/java/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/java/) - [API Reference](https://reference.aspose.org/pdf/java/) Create and save a minimal document to verify the setup: ```java try (Document doc = new Document()) { PageCollection pages = doc.getPages(); Page page = pages.add(); doc.save("output.pdf"); System.out.println("Pages: " + pages.getCount()); } ``` The `Document` class constructor accepts a file path or stream for accessing existing files, or can be called with no arguments to create a blank document. Pages are managed through `PageCollection`, accessible via `Document.getPages()`. Each `Page` exposes its geometry via `getMediaBox()`, `getCropBox()`, and `getRotate()`, and gives access to resources, content operators, and annotations. ```java try (Document doc = new Document()) { PageCollection pages = doc.getPages(); Page page = pages.add(); // page.getMediaBox() -> Rectangle with width/height // page.getAnnotations() -> AnnotationCollection doc.save("output.pdf"); } ``` The `PdfFileEditor` class provides `concatenate()` for merging multiple documents and `resizeContents()` with `ContentsResizeParameters` for adjusting content layout within existing page boundaries. ## Annotations Aspose.PDF FOSS for Java implements the full PDF annotation hierarchy rooted at the abstract `Annotation` class. Concrete annotation types include `WidgetAnnotation` for form controls, `FreeTextAnnotation` for text callouts, `HighlightAnnotation` and `UnderlineAnnotation` for markup, and `CircleAnnotation` and `CaretAnnotation` for graphical notes. Each annotation is associated with a `Page` and a `Rectangle` defining its location. Visual properties are controlled through `AppearanceCharacteristics`, which exposes `setBorder()`, `setBackground()`, `setRotate()`, and `setCaption()` methods. Annotations are added to a page via `page.getAnnotations().add(annotation)`. ```java try (Document doc = new Document()) { PageCollection pages = doc.getPages(); Page page = pages.add(); WidgetAnnotation w = new WidgetAnnotation(page, new Rectangle(0, 0, 100, 50)); w.getCharacteristics().setBorder(Color.fromRgb(1, 0, 0)); w.getCharacteristics().setCaption("Submit"); page.getAnnotations().add(w); doc.save("annotated.pdf"); } ``` ## Interactive Form Fields The `Form` class, accessible via `Document.getForm()`, manages all AcroForm fields. The library provides `ButtonField`, `CheckboxField`, `RadioButtonField`, `TextBoxField`, `ComboBoxField`, and `ListBoxField` for building fillable forms. `FormEditor` is a facade class for working with form fields in a bound document. Radio button groups are created with `RadioButtonField`, which accepts a page and supports `addOption()` to add selectable choices, each associated with a `Rectangle` for its visual location. The `setValue()` method programmatically selects an option. ```java try (Document doc = new Document()) { PageCollection pages = doc.getPages(); Page page = pages.add(); RadioButtonField radio = new RadioButtonField(page); radio.setPartialName("answer"); radio.addOption("Yes", new Rectangle(50, 50, 70, 70)); radio.addOption("No", new Rectangle(50, 80, 70, 100)); doc.getForm().add(radio, 1); radio.setValue("Yes"); doc.save("form.pdf"); } ``` ## Security: AES Encryption The `AESCipher` class implements AES encryption in CBC mode for encrypting and decrypting data byte arrays embedded in PDF documents. `AESCipher.encrypt(key, data)` returns the encrypted ciphertext, and `AESCipher.decrypt(key, data)` retrieves the original plaintext. For explicit IV control, `encryptWithIV(key, iv, plaintext)` and `decryptWithIV(key, iv, cipherText)` provide deterministic operation. ## PDF/A Compliance Validation The library includes `ActionRules` and `ActionFixes` for PDF/A compliance validation and correction. `ActionRules.validate()` checks for forbidden actions in catalog, page, and widget entries. `ActionFixes` provides methods such as `removeCatalogAA()`, `removePageAA()`, and `removeWidgetAA()` to fix non-compliant action dictionaries. Similarly, `AnnotationRules` and `AnnotationFixes` handle annotation compliance. ## Artifacts: Headers, Footers, and Watermarks The `Artifact` class models page decorations such as headers, footers, watermarks, and background images. `ArtifactCollection`, accessible via page resources, allows enumeration and removal of artifact objects. Iterating `page.getArtifacts()` and calling `ArtifactCollection.delete(artifact)` removes specific artifacts without modifying document content streams directly. ## Page Rendering The `BmpDevice` class renders PDF pages directly to BMP image files using `process(page, outputPath)`. This is useful for thumbnail generation, document preview, or image-based processing pipelines. ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) - [Aspose.PDF for Java — Enterprise Product](https://products.aspose.com/pdf/java/) --- # Core Features of Aspose.PDF FOSS for Java URL: https://blog.aspose.org/pdf/java/pdf-core-features-java/ Aspose.PDF FOSS for Java is an MIT-licensed Java library for creating and editing PDF documents. This post covers text-markup annotations, free-text callouts with FreeTextAnnotation, document-level actions with DocumentActions, the DecodeLimits guard for stream filters, and diagnostic logging with AsposePdfLogging. --- Product: Aspose.PDF Platform: java Page Type: index Canonical URL: https://blog.aspose.org/pdf/java/pdf-core-features-java/ --- # Core Features of Aspose.PDF FOSS for Java ## Introduction Aspose.PDF FOSS for Java is an MIT-licensed Java library for creating and editing PDF documents. Its classes are organized under the `org.aspose.pdf` package and its sub-packages (`org.aspose.pdf.annotations`, `org.aspose.pdf.forms`, `org.aspose.pdf.facades`, and others), and `Document` is the entry point for most workflows. The library has no third-party runtime dependencies; the only dependency in its Maven build is JUnit, at test scope. The [library announcement](/pdf/java/java-pdf-create-edit-library/), the [facades post](/pdf/java/pdf-facades-in-java/), and the [page-editing post](/pdf/java/pdf-page-editing-java/) already cover document creation, form fields, the facade classes for extraction, encryption, and stamping, and page operations with `PdfFileEditor`. This post covers five other areas of the same API that those posts do not demonstrate: text-markup annotations, free-text callouts, document-level actions, a size guard on stream decoding, and diagnostic logging. Each area is a small, self-contained API. The sections below show the calls, the defaults, and the edge cases that the library's own tests pin down. --- ## Key Features ### Text Markup Annotations `HighlightAnnotation`, `UnderlineAnnotation`, `StrikeOutAnnotation`, and `SquigglyAnnotation` each take a `Page` and a `Rectangle`. The constructor derives the annotation's quad points from the rectangle, so `getQuadPoints()` returns eight values without any manual calculation. For the rectangle `(100, 200, 300, 250)` the result is `[100, 250, 300, 250, 100, 200, 300, 200]`: top-left, top-right, bottom-left, then bottom-right. `setQuadPoints()` replaces the derived values with your own eight-value array, and an annotation rebuilt from an existing dictionary keeps the quad points already stored there. `getSubtype()` returns the PDF subtype name: `Highlight`, `Underline`, `StrikeOut`, or `Squiggly`. Constructing an annotation does not attach it to the page. Add it with `page.getAnnotations().add(...)`. ```java try (Document doc = new Document()) { Page page = doc.getPages().add(); HighlightAnnotation highlight = new HighlightAnnotation(page, new Rectangle(100, 200, 300, 250)); double[] quadPoints = highlight.getQuadPoints(); UnderlineAnnotation underline = new UnderlineAnnotation(page, new Rectangle(50, 100, 200, 120)); StrikeOutAnnotation strikeOut = new StrikeOutAnnotation(page, new Rectangle(50, 140, 200, 160)); SquigglyAnnotation squiggly = new SquigglyAnnotation(page, new Rectangle(50, 180, 200, 200)); page.getAnnotations().add(highlight); page.getAnnotations().add(underline); page.getAnnotations().add(strikeOut); page.getAnnotations().add(squiggly); doc.save("markup.pdf"); } ``` ### Free-Text Callouts `FreeTextAnnotation` places text directly on a page. Its three-argument constructor takes a `DefaultAppearance`, which carries the font name, font size, and text color. Three properties shape the callout: - `setIntent()` takes a `FreeTextIntent`: `FreeText`, `FreeTextCallout`, or `FreeTextTypeWriter`. A new annotation reports `Undefined`, and passing `null` returns it to that state. - `setCallout()` takes the callout line as an array of two or three `{x, y}` points. An array of any other length is ignored and the existing callout stays in place; `null` removes the callout. - `setEndingStyle()` takes a `LineEnding` value such as `OpenArrow` or `Diamond`. A new annotation reports `LineEnding.None`. ```java try (Document doc = new Document()) { Page page = doc.getPages().add(); DefaultAppearance da = new DefaultAppearance("Helv", 10, Color.BLACK); FreeTextAnnotation note = new FreeTextAnnotation(page, new Rectangle(50, 50, 200, 100), da); note.setContents("Check this value"); note.setIntent(FreeTextIntent.FreeTextCallout); note.setCallout(new double[][] ); note.setEndingStyle(LineEnding.OpenArrow); page.getAnnotations().add(note); doc.save("callout.pdf"); } ``` The saved annotation dictionary stores these values as `/IT`, `/CL`, and `/LE`. ### Document-Level Actions `Document.getActions()` returns a `DocumentActions` view of the document catalog. `setOpenAction()` stores an action in the catalog's `/OpenAction` entry. Five further triggers, `setBeforeClosing()`, `setBeforeSaving()`, `setAfterSaving()`, `setBeforePrinting()`, and `setAfterPrinting()`, are stored independently in the catalog's `/AA` additional-actions dictionary. Each getter returns `null` until its trigger is set. Passing `null` to a setter removes that entry, and removing the last trigger also removes the `/AA` dictionary. Actions are `PdfAction` instances; `GoToURIAction` is an alias of `UriAction`, and its `getType()` returns `URI`. The `DocumentActions` object is a live view, so a later call to `getActions()` sees changes made through an earlier one, and the triggers are read back when the saved file is opened again. ```java try (Document doc = new Document()) { doc.getPages().add(); DocumentActions actions = doc.getActions(); actions.setOpenAction(new GoToURIAction("https://example.com")); actions.setBeforeSaving(new GoToURIAction("https://example.com/saving")); PdfAction open = doc.getActions().getOpenAction(); if (open instanceof UriAction) { System.out.println(((UriAction) open).getUri()); } actions.setBeforeSaving(null); // removes /WS; /AA is removed once it is empty doc.save("actions.pdf"); } ``` ### Decode Limits for Stream Filters PDF streams are stored in encoded form, and a corrupt or malicious stream can expand to far more than its stored size. `DecodeLimits` is a guard shared by the FlateDecode, LZWDecode, and RunLengthDecode filters. When a stream's decoded output exceeds the cap, the filter throws `DecodeSizeLimitException`, a subclass of `IOException`, instead of decoding until the heap is exhausted. The default cap is 256 MB per decoded stream (`DecodeLimits.DEFAULT_MAX_DECODED_BYTES`). To change it, set the system property named by `DecodeLimits.PROPERTY`, which is `aspose.pdf.maxDecodedStreamBytes`, to a size in bytes; a value of `0` or less disables the guard. The property is read on each decode, so it can be changed at runtime. ```java static byte[] decodeFlate(byte[] encoded) { // Lower the cap to 16 MB (16777216 bytes) for this process System.setProperty(DecodeLimits.PROPERTY, "16777216"); try { return new FlateFilter().decode(encoded, null); } catch (IOException e) { // "FlateDecode: decoded output exceeds 16777216 bytes - likely a corrupt stream // or decompression bomb (override with -Daspose.pdf.maxDecodedStreamBytes)" return null; } } ``` Streams under the cap decode as usual. `FlateFilter` and `RunLengthFilter` both round-trip data through `encode()` and `decode()` when the output stays under the limit. ### Diagnostic Logging The library logs through `java.util.logging` under the `org.aspose.pdf` logger and is silent by default: the level is `OFF`. `AsposePdfLogging` turns logging on. - `setLevel(Level)` sets the level from code; `null` returns the library to `OFF`. `getLevel()` reads it back. - The `aspose.pdf.log` system property (also available as `AsposePdfLogging.LOG_PROPERTY`) sets it from the command line. `configureFromSystemProperty()` applies the property and also runs when the class loads. The values `on` and `warning` select `WARNING`, `verbose` selects `FINE`, `debug` selects `ALL`, any `java.util.logging.Level` name such as `SEVERE` is accepted, and an unrecognized value falls back to `OFF`. `WARNING` lets the engine's warnings through; `FINE`, the `verbose` setting, also lets the parser's recovery details through. `AsposePdfLogging` changes only the `org.aspose.pdf` logger subtree. It does not change the level of the root logger, and the library logger does not pass records to the root logger's handlers. If logging is enabled and no handler is attached to the library logger, a console handler is installed. ```java // Equivalent to starting the JVM with -Daspose.pdf.log=warning AsposePdfLogging.setLevel(Level.WARNING); System.setProperty(AsposePdfLogging.LOG_PROPERTY, "verbose"); AsposePdfLogging.configureFromSystemProperty(); System.out.println(AsposePdfLogging.getLevel()); // FINE ``` --- ## Quick Start Add the dependency to your build: The following example creates a page, adds a highlight and a free-text callout, and saves the document: ```java import org.aspose.pdf.*; import org.aspose.pdf.annotations.*; try (Document doc = new Document()) { Page page = doc.getPages().add(); page.getAnnotations().add(new HighlightAnnotation(page, new Rectangle(100, 200, 300, 250))); FreeTextAnnotation note = new FreeTextAnnotation(page, new Rectangle(50, 50, 200, 100), new DefaultAppearance("Helv", 10, Color.BLACK)); note.setContents("Check this value"); note.setIntent(FreeTextIntent.FreeTextCallout); note.setCallout(new double[][] ); page.getAnnotations().add(note); doc.save("core-features.pdf"); } ``` --- ## Supported Formats Format support as confirmed by the library's load and save options and rendering devices: | Format | Extension | Read | Write | |--------|-----------|------|-------| | PDF | pdf | ✓ | ✓ | | HTML | html | ✓ | ✓ | | DOCX | docx | ✓ | ✓ | | DOC | doc | ✓ | ✓ | | XFDF | xfdf | ✓ | ✓ | | BMP | bmp | — | ✓ | | GIF | gif | — | ✓ | | JPEG | jpeg | — | ✓ | | TIFF | tiff | — | ✓ | | Text | txt | — | ✓ | --- ## Open Source & Licensing Aspose.PDF FOSS for Java is released under the MIT license, which permits commercial use, modification, and redistribution. The source code and issue tracker are at [github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java](https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java). The library targets Java 11 or later. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/java/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/java/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/java/) - [API Reference](https://reference.aspose.org/pdf/java/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) - [Aspose.PDF for Java — Enterprise Product](https://products.aspose.com/pdf/java/) --- # Working with PDF Facades in Java URL: https://blog.aspose.org/pdf/java/pdf-facades-in-java/ Aspose.PDF FOSS for Java provides a facades layer with PdfAnnotationEditor, PdfBookmarkEditor, PdfFileSecurity, PdfFileStamp, and PdfExtractor for targeted PDF manipulation without loading the full document object model. --- Product: Aspose.PDF Platform: java Page Type: index Canonical URL: https://blog.aspose.org/pdf/java/pdf-facades-in-java/ --- # Working with PDF Facades in Java ## The Facades Layer in Aspose.PDF FOSS for Java Aspose.PDF FOSS for Java includes a facades layer — a set of high-level, task-focused classes that provide targeted operations on PDF documents without requiring navigation of the full PDF object model. Each facade class follows the same pattern: bind a document, perform operations, save the result. All facade classes reside in the `org.aspose.pdf.facades` package: ```java import org.aspose.pdf.facades.*; ``` ## PdfAnnotationEditor: Flatten and Remove Annotations `PdfAnnotationEditor` provides operations for managing annotations in bulk: flattening them into the page content, removing all annotations, or removing specific annotation types by name. ```java try (PdfAnnotationEditor editor = new PdfAnnotationEditor()) { editor.bindPdf("annotated.pdf"); // Flatten all annotations into the page content stream editor.flattenAnnotations(); editor.save("flat.pdf"); } ``` The `deleteAnnotations(annotationType)` overload accepts an annotation type string such as `"Highlight"` or `"Widget"` to remove only annotations of that type. `countAnnotations()` returns the total annotation count across all pages. ## PdfBookmarkEditor: Create and Delete Bookmarks `PdfBookmarkEditor` manages the PDF outline tree (bookmarks). It exposes methods for creating new bookmarks with `createBookmarks()`, deleting all bookmarks with `deleteBookmarks()`, and removing bookmarks by title with `deleteBookmarkByTitle()`. ```java try (PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor()) { bookmarkEditor.bindPdf("input.pdf"); // Remove all bookmarks from the document bookmarkEditor.deleteBookmarks(); bookmarkEditor.save("no-bookmarks.pdf"); } ``` The `bindPdf(document)` overload accepts a `Document` object directly, enabling use in pipelines where the document is already loaded into memory. ## PdfContentEditor: Text Replacement `PdfContentEditor` supports targeted text replacement within PDF content streams. `replaceText(searchText, replaceText)` substitutes all occurrences of a string across the entire document; `replaceText(searchText, pageNumber, replaceText)` limits the replacement to a single page. ```java try (PdfContentEditor contentEditor = new PdfContentEditor()) { contentEditor.bindPdf("template.pdf"); contentEditor.replaceText("", "Acme Corp"); contentEditor.save("output.pdf"); } ``` `TextReplaceOptions` controls whether the replacement should preserve the original font and size or inherit text properties from the surrounding content. `getStamps(pageNumber)` returns `StampInfo` objects for all stamps on a page, and `deleteStampById()` removes a specific stamp by its identifier. ## PdfFileSecurity: Encryption and Permissions `PdfFileSecurity` manages document-level security including encryption, decryption, and access permissions. The constructor variants accept file paths, streams, or an existing `Document` instance alongside the output destination. `DocumentPrivilege` represents the access permissions for the encrypted document. Use `DocumentPrivilege.getForbidAll()` to deny all user operations, or `DocumentPrivilege.getAllowAll()` to grant full access. ```java try (PdfFileSecurity security = new PdfFileSecurity("input.pdf", "secured.pdf")) { DocumentPrivilege privilege = DocumentPrivilege.getForbidAll(); privilege.setAllowPrint(true); security.encryptFile("userPass", "ownerPass", privilege, KeySize.x256); } ``` `decryptFile(ownerPassword)` removes encryption when the owner password is known. The `Algorithm` enum provides `RC4` and `AES` algorithm families; `KeySize` specifies the key length. ## PdfFileStamp: Adding Stamps and Page Numbers `PdfFileStamp` adds text and image stamps to PDF pages and can automatically generate formatted page numbers. Stamps are positioned using coordinate-based placement on each page. ```java try (PdfFileStamp stamp = new PdfFileStamp("input.pdf", "stamped.pdf")) { // Add formatted page numbers to all pages stamp.addPageNumber("Page #", PageNumberingStyle.NumeralsArabic, 0, 0, 0, 20); } ``` ## PdfExtractor: Text and Image Extraction `PdfExtractor` provides a pull-based API for extracting text and images from PDF documents. After binding a document, call `extractText()` to trigger text extraction, then iterate with `hasNextPageText()` and `getNextPageText()`: ```java try (PdfExtractor extractor = new PdfExtractor()) { extractor.bindPdf("document.pdf"); extractor.extractText(); while (extractor.hasNextPageText()) { String pageText = extractor.getNextPageText(); // Collect extracted page content } } ``` For image extraction, `extractImage()` triggers the extraction and `hasNextImage()` / `getNextImage(outputStream)` iterate over the extracted images. The `getPassword()` and `setPassword()` methods support encrypted documents. ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/java/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/java/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/java/) - [API Reference](https://reference.aspose.org/pdf/java/) Add the Maven dependency: All facade classes require Java 11 or later. Aspose.PDF FOSS for Java is MIT-licensed and available at `https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java`. ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # PDF Document Manipulation with Aspose.PDF FOSS for Java URL: https://blog.aspose.org/pdf/java/pdf-page-editing-java/ Aspose.PDF FOSS for Java exposes PdfFileEditor for concatenating, splitting, extracting, and resizing PDF pages. This post covers the key file manipulation and page management APIs available in the MIT-licensed library. --- Product: Aspose.PDF Platform: java Page Type: index Canonical URL: https://blog.aspose.org/pdf/java/pdf-page-editing-java/ --- # PDF Document Manipulation with Aspose.PDF FOSS for Java ## PDF Document Manipulation in Java Aspose.PDF FOSS for Java provides a rich set of APIs for manipulating existing PDF documents — splitting, concatenating, extracting pages, inserting page ranges, and resizing content within pages. These capabilities are concentrated in `PdfFileEditor` and its companion classes `ContentsResizeParameters` and `ContentsResizeValue`. ## PdfFileEditor: Core Page Operations The `PdfFileEditor` class is the central facility for high-level PDF file operations. It provides methods for concatenating multiple PDF files, extracting page subsets, splitting a document into individual pages, and inserting pages from one document into another at a specific position. ```java PdfFileEditor editor = new PdfFileEditor(); // Concatenate two documents into one editor.concatenate("first.pdf", "second.pdf", "combined.pdf"); // Extract pages 2 through 5 to a new file editor.extract("source.pdf", 2, 5, "extracted.pdf"); ``` Key methods include: - `concatenate(inputFiles, outputFile)` — merges multiple documents in order - `extract(inputFile, startPage, endPage, outputFile)` — exports a contiguous range - `extract(inputFile, pageNumbers, outputFile)` — exports a non-contiguous set - `splitToPages(inputFile)` — splits into one `ByteArrayOutputStream` per page - `insert(inputFile, insertPosition, portFile, startPage, endPage, outputFile)` — inserts a range - `delete(inputFile, pageNumbers, outputFile)` — removes specific pages - `append(inputFile, portFile, startPage, endPage, outputFile)` — appends a page range For large files, `setUseDiskBuffer(true)` switches internal storage from heap to disk. ## Content Resizing with ContentsResizeParameters `PdfFileEditor.resizeContents()` adjusts content within existing page boundaries. Each margin — left, right, top, bottom — and the content width and height are specified as `ContentsResizeValue` instances, constructed via the factory methods `ContentsResizeValue.percents(value)` or `ContentsResizeValue.units(value)`. ```java try (Document doc = new Document("input.pdf")) { PdfFileEditor editor = new PdfFileEditor(); ContentsResizeParameters params = new ContentsResizeParameters( ContentsResizeValue.percents(10), // left margin ContentsResizeValue.percents(80), // content width ContentsResizeValue.percents(10), // right margin ContentsResizeValue.percents(10), // top margin ContentsResizeValue.percents(80), // content height ContentsResizeValue.percents(10) // bottom margin ); editor.resizeContents(doc, params); doc.save("resized.pdf"); } ``` The six-argument constructor for `ContentsResizeParameters` accepts values in the order: leftMargin, contentsWidth, rightMargin, topMargin, contentsHeight, bottomMargin. All six must sum to 100% when using percentage-based values, or match the page dimensions when using absolute point values. ## Resizing Specific Pages When only a subset of pages requires resizing, the overload that accepts an integer array of page numbers targets those pages while leaving the rest unchanged: ```java PdfFileEditor editor = new PdfFileEditor(); ContentsResizeParameters params = new ContentsResizeParameters( ContentsResizeValue.units(28), // left margin in points ContentsResizeValue.units(540), // content width ContentsResizeValue.units(28), // right margin ContentsResizeValue.units(28), // top margin ContentsResizeValue.units(786), // content height ContentsResizeValue.units(28) // bottom margin ); // Only resize pages 1 and 3 editor.resizeContents(doc, new int[]{1, 3}, params); ``` `ContentsResizeValue.getValue()` and `isPercent()` allow inspecting the stored value and determining whether it represents a percentage or an absolute point count. ## Booklet and N-Up Layout `PdfFileEditor` includes `makeBooklet()` for imposing pages in two-sided booklet order and `makeNUp()` for tiling multiple pages per sheet. Both methods accept file paths or streams: ```java PdfFileEditor editor = new PdfFileEditor(); // Print as a folded booklet editor.makeBooklet("input.pdf", "booklet.pdf"); // Tile 2 columns × 3 rows per sheet editor.makeNUp("input.pdf", "nup.pdf", 2, 3); ``` ## PdfPageEditor: Per-Page Zoom Control `PdfPageEditor` targets individual page properties such as zoom level. `setZoom()` accepts a float multiplier that controls the initial magnification when the document is opened in a viewer: ```java PdfPageEditor pageEditor = new PdfPageEditor(); pageEditor.bindPdf("input.pdf"); pageEditor.setZoom(1.5f); pageEditor.save("zoomed.pdf"); ``` Values of `0.0` or negative are rejected — `getZoom()` returns `1.0` in those cases. This makes `PdfPageEditor` suitable for preparing documents that must open at a specific magnification for accessibility or kiosk display use cases. ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/java/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/java/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/java/) - [API Reference](https://reference.aspose.org/pdf/java/) Add the Maven dependency and import the facades package: ```java import org.aspose.pdf.*; import org.aspose.pdf.facades.*; ``` Aspose.PDF FOSS for Java is MIT-licensed and available at `https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Java`. Commercial use is permitted under the MIT license terms. If your project requires enterprise-grade support, extended format coverage, or cloud integration, the [Aspose.PDF — Enterprise Product Family](https://products.aspose.com/pdf/) is a separate commercial offering. ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.PDF FOSS for .NET URL: https://blog.aspose.org/pdf/net/ --- Product: Aspose.PDF Platform: net Page Type: index Canonical URL: https://blog.aspose.org/pdf/net/ --- # Aspose.PDF FOSS for .NET Articles and tutorials for Aspose.PDF FOSS for .NET. Covers PDF creation, document management, annotation handling, form processing, text extraction, and encryption using the MIT-licensed .NET 8+ library. ## Related Resources - [Aspose.PDF for .NET — Enterprise Product](https://products.aspose.com/pdf/net/) ## Related Topics - [Introducing Aspose.PDF FOSS for .NET](https://blog.aspose.org/pdf/net/introducing-pdf-foss-net/) - [PDF Annotations and Forms in .NET: A Complete Guide](https://blog.aspose.org/pdf/net/pdf-annotations-forms-net/) - [PDF Core Document Management with Aspose.PDF FOSS for .NET](https://blog.aspose.org/pdf/net/pdf-core-management-net/) - [PDF Document Management in .NET: Open, Create, and Transform](https://blog.aspose.org/pdf/net/pdf-document-management-in-net/) --- # Introducing Aspose.PDF FOSS for .NET URL: https://blog.aspose.org/pdf/net/introducing-pdf-foss-net/ Aspose.PDF FOSS for .NET is a free, MIT-licensed .NET 8+ library for working with PDF documents. It exposes 805 API classes covering document creation, annotations, text extraction, form fields, and interactive actions — with no proprietary dependencies. --- Product: Aspose.PDF Platform: net Page Type: index Canonical URL: https://blog.aspose.org/pdf/net/introducing-pdf-foss-net/ --- # Introducing Aspose.PDF FOSS for .NET Aspose.PDF FOSS for .NET is a free, MIT-licensed .NET library for reading, creating, and manipulating PDF documents. Released under a permissive open-source license, it removes the traditional barrier to enterprise-grade PDF capabilities — every feature in the library is available without purchasing a commercial license. ## What Is Aspose.PDF FOSS for .NET? The library targets .NET 8 and later. It is published to NuGet under the package ID `Aspose.Pdf.Foss` and can be added to any .NET 8+ project with a single command: The primary namespace is `Aspose.Pdf`, with related namespaces including `Aspose.Pdf.Text`, `Aspose.Pdf.Forms`, and `Aspose.Pdf.Facades`. The library exposes 805 public API classes backed by 7,488 documented claims and 100 code snippets extracted directly from the test suite. ## Core Capabilities The API covers the full lifecycle of a PDF document: - **Document creation and loading** — `Document.Create()` produces a blank document; `Document.Open(data)` loads an existing PDF from a byte array or stream. - **Page and content access** — the `Pages` collection provides 1-based indexed access to individual pages, each of which exposes annotations, operators, and content streams. - **Text extraction** — `TextFragmentAbsorber` visits a page and collects every text fragment, with optional search-phrase filtering and regular expression support. - **Interactive actions** — `PdfAction.CreateUri`, `PdfAction.CreateGoTo`, `PdfAction.CreateJavaScript`, and `PdfAction.CreateLaunch` cover the standard PDF action types. - **Annotations** — `AnnotationCollection.AddLinkAnnotation` attaches a link annotation with an associated action to any rectangular region on a page. - **Forms** — the `Aspose.Pdf.Forms` namespace and `Aspose.Pdf.Facades` provide access to AcroForm fields, appearance formatting, and field-level JavaScript extensions. --- ## Opening a Document and Adding a Link The following example demonstrates the round-trip pattern: create a new PDF document, add a URI action link annotation to the first page, save to a stream, and reload to verify the annotation persists. ```csharp using var doc = Document.Create(); doc.Pages.Add(); var page = doc.Pages[1]; var action = PdfAction.CreateUri("https://aspose.com"); page.Annotations.AddLinkAnnotation(new Rectangle(50, 700, 200, 720), action); using var ms = new MemoryStream(); doc.Save(ms); ms.Position = 0; using var doc2 = Document.Open(ms.ToArray()); var annot = (LinkAnnotation)doc2.Pages[1].Annotations[1]; Console.WriteLine(annot.Uri); // https://aspose.com ``` The `Document.Open` static method accepts a `byte[]` or a stream. `doc.Pages[1]` accesses the first page by 1-based index — the same index convention used throughout the library. After saving to a `MemoryStream`, the document can be reloaded and all annotations are preserved. --- ## Searching Text on a Page `TextFragmentAbsorber` provides keyword search over the content stream of any page. Pass a search phrase to the constructor to restrict results, or use the no-argument overload to collect all fragments: ```csharp using var doc = Document.Open("path/to/document.pdf"); var absorber = new TextFragmentAbsorber("Hello"); absorber.Visit(doc.Pages[1]); foreach (var fragment in absorber.TextFragments) { Console.WriteLine($"Found: {fragment.Text}"); } ``` Each `TextFragment` in the resulting collection exposes properties including `Text`, `FontSize`, and positional data, making it straightforward to build search, highlight, or redaction workflows on top of the extracted fragments. --- ## MIT License and Open Development All source code is published on GitHub and distributed under the MIT License. There is no evaluation watermark, no usage limit, and no separate license file to manage. The `Document.IsLicensed` property always returns `true` in the FOSS build. The package is currently at version `0.1.0-alpha`, reflecting active development. The API surface is already substantial — 805 classes, 7,488 claims — and the alpha designation signals that API signatures may evolve before the 1.0 release. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/net/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/net/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/net/) - [API Reference](https://reference.aspose.org/pdf/net/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) - [Aspose.PDF for .NET — Enterprise Product](https://products.aspose.com/pdf/net/) --- # PDF Annotations and Forms in .NET: A Complete Guide URL: https://blog.aspose.org/pdf/net/pdf-annotations-forms-net/ Explore the annotation and form capabilities of Aspose.PDF FOSS for .NET — add sticky notes, hyperlinks, highlights, shape annotations, and read interactive AcroForm fields, all under the MIT License. --- Product: Aspose.PDF Platform: net Page Type: index Canonical URL: https://blog.aspose.org/pdf/net/pdf-annotations-forms-net/ --- # PDF Annotations and Forms in .NET: A Complete Guide Aspose.PDF FOSS for .NET ships with a rich set of annotation and form-field APIs that let you mark up, link, and interact with PDF documents entirely in managed code — no license key required. ## Annotations at a glance The library's `AnnotationCollection` class provides typed helper methods for every standard PDF annotation. Adding a sticky note is a single call: ```csharp page.Annotations.AddTextAnnotation( new Rectangle(72, 720, 200, 740), contents: "Review needed", title: "Editor", open: true); ``` Link annotations combine a clickable rectangle with a `PdfAction`: ```csharp var action = PdfAction.CreateUri("https://aspose.com"); page.Annotations.AddLinkAnnotation( new Rectangle(50, 700, 200, 720), action); ``` The same pattern applies to highlights, underlines, squares, circles, lines, and ink (freehand) annotations — each with a dedicated `Add*` method. ## Interactive form fields AcroForm fields are accessed through `Document.Form`. Iterate `Form.Fields` to read field values, or use the `Form` facade for high-level fill operations: ```csharp using var form = new Form("input.pdf", "output.pdf"); form.FillField("Name", "Alice"); form.Save(); ``` Field subclasses include `TextBoxField`, `CheckboxField`, `RadioButtonField`, `ComboBoxField`, `ListBoxField`, and `SignatureField`. ## Flattening and the visitor pattern Call `Annotation.Flatten()` to burn an annotation's visual appearance into the page content. Use `AnnotationSelector` to filter annotations by type through the visitor pattern — no manual casting required. ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/net/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/net/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/net/) - [API Reference](https://reference.aspose.org/pdf/net/) Install with: For step-by-step guides, see the [Annotations and Forms developer guide](https://docs.aspose.org/pdf/net/developer-guide/annotations-forms/) and the [how-to article](https://kb.aspose.org/pdf/net/how-to-add-pdf-annotations-dotnet/). --- ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # PDF Core Document Management with Aspose.PDF FOSS for .NET URL: https://blog.aspose.org/pdf/net/pdf-core-management-net/ Aspose.PDF FOSS for .NET provides a .NET 8+ API for core PDF document management tasks including document creation, page access, annotation handling, text fragment extraction, and interactive PDF actions — all under the MIT license. --- Product: Aspose.PDF Platform: net Page Type: index Canonical URL: https://blog.aspose.org/pdf/net/pdf-core-management-net/ --- # PDF Core Document Management with Aspose.PDF FOSS for .NET Core PDF document management covers the operations that appear in nearly every PDF workflow: opening or creating a document, accessing pages and their content, reading and writing annotations, extracting text, and working with interactive actions. Aspose.PDF FOSS for .NET provides a .NET 8+ API that handles all of these tasks through a consistent object model centered on the `Document` and `Page` types. ## Document Lifecycle: Create, Open, Save Every workflow starts with either creating a new document or loading an existing one. `Document.Create()` returns a new, empty `Document` instance. `Document.Open(data)` accepts a `byte[]` or `Stream` and parses the PDF structure: ```csharp using var doc = Document.Create(); doc.Pages.Add(); var page = doc.Pages[1]; var action = PdfAction.CreateUri("https://aspose.com"); page.Annotations.AddLinkAnnotation(new Rectangle(50, 700, 200, 720), action); using var ms = new MemoryStream(); doc.Save(ms); ms.Position = 0; using var doc2 = Document.Open(ms.ToArray()); var annot = (LinkAnnotation)doc2.Pages[1].Annotations[1]; Console.WriteLine(annot.Uri); // https://aspose.com ``` This snippet opens a minimal PDF, adds a link annotation to page 1, saves to a `MemoryStream`, and verifies that the annotation is preserved after reload. The `Document.Save(Stream)` overload writes the full updated structure; `Document.ToArray()` returns the bytes directly. --- ## Page Access and the Pages Collection Pages are accessed through the `Pages` property using a 1-based integer index: `doc.Pages[1]` returns the first page, `doc.Pages[doc.Pages.Count]` returns the last. Each `Page` object exposes: - `Annotations` — the `AnnotationCollection` for that page, supporting `AddLinkAnnotation` and enumeration of existing annotations by type. - Content stream operators — low-level access to page drawing commands via the `Operators` collection. The 1-based index is consistent throughout the API: annotation lookups, GoTo action destination page indices, and all other page references use the same convention. --- ## Text Extraction with TextFragmentAbsorber `TextFragmentAbsorber` is the standard entry point for reading text from a PDF page. Use the no-argument constructor to extract all fragments, or pass a search phrase to filter to matching text: ```csharp using var doc = Document.Open("path/to/document.pdf"); var absorber = new TextFragmentAbsorber("Hello"); absorber.Visit(doc.Pages[1]); foreach (var fragment in absorber.TextFragments) { Console.WriteLine($"Found: {fragment.Text} size={fragment.FontSize}"); } ``` Call `absorber.Visit(page)` to process a single page. The resulting `TextFragments` collection contains `TextFragment` objects; each exposes `Text` (the string content) and `FontSize` (the rendered point size). A second overload `TextFragmentAbsorber(searchPhrase, isRegex)` accepts a regular expression flag for pattern-based search. --- ## Interactive Actions `PdfAction` is the factory class for all standard PDF action types. Four static factory methods cover the most common cases: - `PdfAction.CreateUri(uri)` — opens a URL in the user's browser. - `PdfAction.CreateGoTo(pageIndex, fitType)` — navigates to a specific page within the document. - `PdfAction.CreateJavaScript(script)` — executes a JavaScript string in the PDF viewer. - `PdfAction.CreateLaunch(filePath)` — launches an external file or application. Actions are attached to pages through annotations. `AnnotationCollection.AddLinkAnnotation(rectangle, action)` places a `LinkAnnotation` over the specified rectangular region with the given action attached: ```csharp using var doc = Document.Create(); doc.Pages.Add(); var page = doc.Pages[1]; var action = PdfAction.CreateUri("https://example.org"); var annot = page.Annotations.AddLinkAnnotation(new Rectangle(10, 10, 100, 30), action); Console.WriteLine(page.Annotations.Count); // 1 Console.WriteLine(annot.AnnotationType); // Link ``` `AnnotationType.Link` confirms the annotation was created as a link type. The `Rectangle` constructor takes left, bottom, right, and top coordinates in PDF user space units. --- ## Document Metadata and Licensing The `Document` class exposes `IsLicensed` (returns `true` in the FOSS build), `JavaScript` (a `JavaScriptCollection` for document-level scripts), and `DocumentActions` for lifecycle events such as `BeforeClosing` and `BeforeSaving`. The FOSS package is installed via NuGet: No license key is required. The MIT license permits use in commercial applications without attribution requirements beyond preserving the license notice. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/net/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/net/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/net/) - [API Reference](https://reference.aspose.org/pdf/net/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # PDF Document Management in .NET: Open, Create, and Transform URL: https://blog.aspose.org/pdf/net/pdf-document-management-in-net/ Deep dive into Aspose.PDF FOSS for .NET document management — open PDFs from files or byte arrays, create new documents, manipulate pages, embed attachments, and convert to HTML, Markdown, SVG, and images. --- Product: Aspose.PDF Platform: net Page Type: index Canonical URL: https://blog.aspose.org/pdf/net/pdf-document-management-in-net/ --- # PDF Document Management in .NET: Open, Create, and Transform The `Document` class is the heart of Aspose.PDF FOSS for .NET. It represents a complete PDF and provides access to every structure inside — pages, annotations, form fields, metadata, and embedded files. ## Opening documents Load a PDF from a file, a byte array, or a stream: ```csharp using var doc = Document.Open(File.ReadAllBytes("input.pdf")); Console.WriteLine($"Pages: {doc.Pages.Count}"); ``` Pages use 1-based indexing: `doc.Pages[1]` is the first page. ## Creating from scratch ```csharp using var doc = new Document(); var page = doc.Pages.Add(); page.Paragraphs.Add(new TextFragment("Hello, PDF!")); doc.Save("hello.pdf"); ``` Tables, floating boxes, headers/footers, and graphs are all paragraph types that the layout engine places automatically. ## Page manipulation Set page geometry, rotation, and bounding boxes: ```csharp var page = doc.Pages[1]; page.SetMediaBox(new Rectangle(0, 0, 612, 792)); page.SetCropBox(new Rectangle(36, 36, 576, 756)); page.SetRotation(90); ``` ## Conversion The library includes dedicated converters for several output formats: | Converter | Output | |-----------|--------| | `PdfToHtmlConverter` | HTML | | `PdfToMarkdownConverter` | Markdown | | `PdfToSvgConverter` | SVG | | `PdfToTextConverter` | Plain text | Rendering to raster images uses device classes (`PngDevice`, `JpegDevice`, `TiffDevice`, `BmpDevice`), each accepting a `Resolution` in DPI. ## PDF/A compliance Validate and convert documents to PDF/A-1B, PDF/A-2B, or PDF/A-3B: ```csharp var options = new PdfFormatConversionOptions( "log.xml", PdfFormat.PDF_A_1B, ConvertErrorAction.Delete); doc.Convert(options); doc.Save("pdfa.pdf"); ``` ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/net/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/net/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/net/) - [API Reference](https://reference.aspose.org/pdf/net/) For full API details, see the [Document Management developer guide](https://docs.aspose.org/pdf/net/developer-guide/document-management/) and the [Conversion and Optimization guide](https://docs.aspose.org/pdf/net/developer-guide/conversion-optimization/). --- ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.PDF FOSS for Python URL: https://blog.aspose.org/pdf/python/introducing-pdf-foss-python/ Aspose.PDF FOSS for Python is a free, MIT-licensed, pure-Python library for creating, reading, editing, rendering, and validating PDF documents. It covers document and page management, text and image placement, annotations, AcroForm fields, encryption, and text extraction through the Document class and a small set of companion classes. --- Product: Aspose.PDF Platform: python Page Type: index Canonical URL: https://blog.aspose.org/pdf/python/introducing-pdf-foss-python/ --- # Introducing Aspose.PDF FOSS for Python ## Introduction Aspose.PDF FOSS for Python is a new open-source library for working with PDF documents from Python code. It is released under the MIT license and implemented entirely in Python — the PDF parser, writer, page rasterizer, and encryption routines are part of the package itself, with required dependencies limited to `cryptography` and `asn1crypto`. Optional extras add Pillow-based image support, Brotli-based WOFF2 font decoding, and HarfBuzz-based complex text shaping. The library is organized around the `Document` class, which loads a PDF from a path, bytes, or a binary stream and exposes its pages through `document.pages`, a `PageCollection` supporting iteration, indexing, and slicing. From there, the API covers adding text and images to pages, reading and modifying annotations, creating and filling AcroForm fields, encrypting and decrypting documents, and extracting text and attachments — the operations needed to build new PDFs or work with existing ones. This release is for developers who need PDF processing inside a Python codebase without a commercial license: report and invoice generation, document ingestion pipelines, form-filling automation, and services that need to render PDF pages to images or extract text for downstream indexing. The project is currently in alpha, so APIs and feature coverage may evolve before the first stable release. Python 3.11 or newer is required. --- ## What's Included ### Document Creation and Loading `PdfDocument()` creates an empty PDF; `PdfDocument(source, password=..., limits=...)` loads an existing one from a path, raw bytes, or a binary stream, and is equivalent to calling `PdfDocument().load_from(source, ...)`. Both raise on a missing file, non‑PDF data, or a missing password rather than returning an empty document. `PdfDocument` is a context manager, so resources are released automatically when the `with` block exits. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() page.add_text("Generated by Aspose.PDF FOSS", x=72, y=720, font_size=14) document.save("report.pdf") with Document("report.pdf") as document: print(f"Pages: {document.page_count}") print(f"PDF version: {document.version}") ``` ### Adding Text and Images `Page.add_text` places Standard‑14 or embedded Unicode text at an `x`/`y` position with a given `font_size`; the `font` argument can be a `FontDescriptor`, raw font bytes, or a path to a TrueType/OpenType font for Unicode outside the Standard‑14 encodings. `Page.add_image` places a raw, JPEG, or PNG image XObject on the page at a specified position and size. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() page.add_text( "Quarterly Summary", x=72, y=740, font_size=16, ) page.add_image( "chart.png", x=72, y=420, width=300, height=200, ) document.save("summary.pdf") ``` ### Annotations Each `Page` exposes its annotations through `page.annotations`, an `AnnotationCollection`. `add(subtype, rect, contents, title, appearance_normal, properties)` creates and inserts an annotation of a standard subtype such as `Square`, `Circle`, `Line`, `Highlight`, or `FreeText`, returning an `Annotation`. Calling `generate_appearance()` on the returned annotation synthesizes an appearance stream from its geometry and properties. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() annotation = page.annotations.add( "Square", (100, 600, 300, 680), "Needs review", properties={"C": [1, 0, 0]}, ) annotation.generate_appearance() document.save("annotated.pdf") ``` ### Form Fields `document.form` returns the document's `Form`, which creates AcroForm fields directly: `add_text_field()`, `add_checkbox()`, `add_radio_group()`, `add_list_box()`, `add_combo_box()`, and `add_push_button()` each accept a field name, a `Page` or page index, and a placement rectangle, returning a `Field`. Setting `field.value` updates the field's value, and `form.flatten()` bakes every field's appearance into static page content. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() form = document.form field = form.add_text_field( "customer_name", page, (72, 700, 300, 720), ) field.value = "Jane Doe" form.flatten() document.save("form.pdf") ``` ### Encryption `Document.encrypt(user_password, owner_password, permissions)` protects a document with a user password, an owner password, and a permission bitmask, returning the same `Document` for chaining. `Document.decrypt(password)` reverses the operation, and the `is_encrypted` property reports the current state. Loading an encrypted document again requires passing `password=` to the constructor or to `load_from()`. ```python from aspose_pdf import Document with Document("report.pdf") as document: document.encrypt(user_password="user-pass", owner_password="owner-pass", permissions=0) document.save("encrypted.pdf") with Document("encrypted.pdf", password="user-pass") as document: print(f"Encrypted: {document.is_encrypted}") ``` ### Text Extraction `PdfExtractor` binds to a source with `bind_pdf()`, then `extract_text()` walks the document's pages. `get_text()` returns all extracted text at once, while `has_next_page_text()` and `get_next_page_text()` iterate the result page by page. `PdfExtractor` is also a context manager. ```python from aspose_pdf import PdfExtractor with PdfExtractor() as extractor: extractor.bind_pdf("report.pdf") extractor.extract_text() while extractor.has_next_page_text(): print(extractor.get_next_page_text()) ``` --- ## Quick Start ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() page.add_text( "Hello from Aspose.PDF FOSS!", x=72, y=720, font_size=18, ) document.save("hello.pdf") with Document("hello.pdf") as document: print(f"Pages: {document.page_count}") print(f"PDF version: {document.version}") ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PDF | .pdf | ✓ | ✓ | | PNG | .png | — | ✓ | | TIFF | .tiff | — | ✓ | PDF is the library's core input and output format, read through `Document`/`load_from()` and written through `Document.save`. PNG and TIFF are page-rendering outputs produced by `Page.render`, `Page.save_as_image`, and `Document.save_page_as_image`. --- ## Open Source & Licensing Aspose.PDF FOSS for Python is distributed under the MIT license, with the full source available at [github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python). The license permits commercial use, modification, and redistribution without a separate agreement. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/python/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/python/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/python/) - [API Reference](https://reference.aspose.org/pdf/python/) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Document Management in Python: Forms, Fonts, and Attachments URL: https://blog.aspose.org/pdf/python/pdf-document-management-python/ Aspose.PDF FOSS for Python exposes document-level APIs for interactive AcroForm fields, embedded file attachments, font discovery, and PDF outlines, layered over the AsposePdfException error hierarchy. This post covers the Field, FileSpecification, FontDescriptor, FontRepository, and OutlineItem classes with working code. --- Product: Aspose.PDF Platform: python Page Type: index Canonical URL: https://blog.aspose.org/pdf/python/pdf-document-management-python/ --- # Document Management in Python: Forms, Fonts, and Attachments ## Introduction Aspose.PDF FOSS for Python centers on the `Document` class, which exposes `pages`, `form`, `outlines`, `tagged_content`, and `attachments` as the entry points for structural, document-level editing. Beyond adding page content, the library covers the operations that make a PDF a complete, distributable artifact: interactive form fields that collect and expose structured data, document-level file attachments, font discovery and embedding for text authoring, and a bookmark tree for navigation. Every one of these areas raises errors through a single exception hierarchy rooted in `AsposePdfException`, so callers can catch package-specific failures without guessing at exception types module by module. This guide shows how to work with that document-management surface: catching and distinguishing `AsposePdfException` subclasses, creating and reading AcroForm fields with `Form` and `Field`, embedding and recovering attachments through `FileSpecification`, resolving fonts with `FontRepository` and `FontRegistry`, and building a bookmark tree with `OutlineCollection` and `OutlineItem`. Each section uses only the classes and methods present in the current package. Aspose.PDF FOSS for Python is a Python package, `aspose-pdf-foss-for-python`, released under the MIT license, requiring Python 3.11 or later. Its top-level module name is `aspose_pdf`. The core package depends only on `cryptography` and `asn1crypto`; optional extras add Pillow-based image decoding, Brotli-based WOFF2 font support, and HarfBuzz-based complex text layout. --- ## Key Features ### Exception Handling with AsposePdfException Every package-specific error in Aspose.PDF FOSS for Python derives from `AsposePdfException`. Most document-processing failures fall under its `PdfException` subclass, which in turn is the base for `PdfParseException` (malformed input), `PdfSecurityException` (encryption and password failures, including `InvalidPasswordException`), and `PdfValidationException` (structural or compliance failures). Catching `AsposePdfException` last, after more specific subclasses, lets a caller react differently to a bad password than to a corrupted file while still having a single fallback for everything else the package can raise. ```python from aspose_pdf import Document from aspose_pdf.exceptions import ( AsposePdfException, InvalidPasswordException, PdfParseException, ) def open_document(path, password=None): try: document = Document() document.load_from(path, password=password) return document except InvalidPasswordException: print(f"{path}: a correct password is required") except PdfParseException as error: print(f"{path}: not a valid PDF ({error})") except AsposePdfException as error: # Catches every other aspose_pdf-specific error not handled above. print(f"{path}: PDF operation failed ({error})") return None ``` ### Interactive Form Fields `Document.form` returns a `Form` facade over the document's AcroForm fields. `Form.add_text_field()`, `add_checkbox()`, and `add_radio_group()` create new terminal fields tied to a page and a widget rectangle, each returning a `Field`. `Field` exposes `name`, `value`, and `field_type` so existing fields can be inspected and updated by name, and `Field.remove()` deletes a field entirely. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() document.form.add_text_field("customer_name", page, (72, 700, 300, 720)) document.form.add_checkbox("subscribe", page, (72, 670, 90, 688), on_value="Yes") document.form.add_radio_group( "plan", page, {"Basic": (72, 630, 90, 648), "Pro": (72, 600, 90, 618)}, value="Basic", ) for field in document.form.fields: print(field.name, field.field_type, field.value) for field in document.form.fields: if field.name == "customer_name": field.value = "Jane Doe" document.form.generate_appearances() document.save("form.pdf") ``` ### Embedded Files and Attachments `Document.add_attachment` embeds bytes as a document-level file attachment, written to the PDF's `/Names /EmbeddedFiles` name tree on save, along with an optional MIME type, description, and creation/modification dates. `Document.embedded_files` reads every attachment back as a typed `FileSpecification` (`name`, `contents`, `mime_type`, `description`, `size`), and `Document.get_embedded_file` looks one up by name. `FileSpecification.save()` writes the recovered bytes to disk. ```python from aspose_pdf import Document with Document() as document: document.pages.add() document.add_attachment( "notes.txt", b"Reviewed and approved.", mime="text/plain", description="Reviewer notes", ) document.save("with-attachment.pdf") with Document() as document: document.load_from("with-attachment.pdf") for spec in document.embedded_files: print(spec.name, spec.mime_type, spec.size) notes = document.get_embedded_file("notes.txt") if notes is not None: notes.save("notes-recovered.txt") ``` ### Font Discovery and Embedding `FontRepository` aggregates font sources and resolves fonts by name across the document. `FontRepository.add_source()` registers a `FontSource` such as `FolderFontSource` (scans a directory, optionally recursively); `FontRepository.find_font()` and `search()` then resolve a font by family, full, or PostScript name, falling back to the standard-font registry. Each match is a `FontDescriptor`, which can be passed directly to `Page.add_text` to embed and subset the font. `FontRegistry` maps common non-standard names (`Arial`, `Times New Roman`, and similar) to their closest Standard-14 equivalent through `search_font_by_name()`. ```python from aspose_pdf import Document, FolderFontSource, FontRepository from aspose_pdf.font_registry import FontRegistry FontRepository.add_source(FolderFontSource("./fonts", scan_subdirectories=True)) descriptor = FontRepository.find_font("Open Sans") if descriptor is None: # Fall back to the closest Standard-14 match for a common font name. descriptor = FontRegistry().search_font_by_name("Arial") with Document() as document: page = document.pages.add() page.add_text( "Rendered with a resolved font", x=72, y=700, font_size=14, font=descriptor, ) document.save("font-sample.pdf") ``` ### Document Outlines and Bookmarks `Document.outlines` returns an `OutlineCollection`, the top-level container for a PDF's bookmark tree. `OutlineCollection.add` appends a top-level `OutlineItem`; `OutlineItem.add()` nests a child bookmark under an existing one. Each `OutlineItem` carries a `title`, a target `page_index`, and `is_bold` / `is_italic` display flags, and exposes its own `children` list. ```python from aspose_pdf import Document from aspose_pdf.outlines import OutlineItem with Document() as document: document.pages.add() document.pages.add() chapter = OutlineItem("Chapter 1: Overview", page_index=0) document.outlines.add(chapter) chapter.add(OutlineItem("Section 1.1", page_index=0, is_italic=True)) document.outlines.add(OutlineItem("Chapter 2: Details", page_index=1, is_bold=True)) document.save("bookmarked.pdf") ``` --- ## Quick Start Install the package, then build a document that combines a bookmark, document metadata, and an attachment in a single script. ```python from aspose_pdf import Document from aspose_pdf.outlines import OutlineItem with Document() as document: page = document.pages.add() page.add_text("Quarterly Report", x=72, y=740, font_size=20) document.outlines.add(OutlineItem("Quarterly Report", page_index=0)) document.info = {"Title": "Quarterly Report"} document.add_attachment( "source-data.csv", b"quarter,total\nQ1,1000\n", mime="text/csv" ) document.save("report.pdf") with Document() as reopened: reopened.load_from("report.pdf") print(reopened.page_count, "page(s),", reopened.info.get("Title")) print([spec.name for spec in reopened.embedded_files]) ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | Yes | Yes | | TIFF | tiff | - | Yes | `Page.render`, `Page.save_as_image`, and `Document.save_page_as_image` also produce PNG raster output alongside TIFF. These are page-rasterization outputs rather than document-loading formats. --- ## Open Source & Licensing Aspose.PDF FOSS for Python is released under the MIT license: no usage restrictions, no runtime fees, and no registration requirements for commercial or personal use. Source code is hosted at [github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python), packaged as `aspose-pdf-foss-for-python`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/python/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/python/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/python/) - [API Reference](https://reference.aspose.org/pdf/python/) - [GitHub Repository](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # The PDF Engine in Python: Rasterization, Stream Filters, and Encryption URL: https://blog.aspose.org/pdf/python/pdf-engine-in-python/ Aspose.PDF FOSS for Python's Document and Page classes are a facade over a lower-level aspose_pdf.engine package that implements PDF parsing, writing, rasterization, stream filtering, and encryption. This post shows how to use the rasterizer, stream codecs, and encryption utilities the engine exposes directly. --- Product: Aspose.PDF Platform: python Page Type: index Canonical URL: https://blog.aspose.org/pdf/python/pdf-engine-in-python/ --- # The PDF Engine in Python: Rasterization, Stream Filters, and Encryption ## Introduction `document.py`, the module that defines Aspose.PDF FOSS for Python's `Document` class, describes it as a class that "wraps the native PDF engine." Concretely, that engine is `aspose_pdf.engine.simple_pdf.SimplePdf`: `Document.load_from` builds a `SimplePdf` instance, and every document-level operation — saving, optimizing, repairing, encrypting — delegates to it. The same is true of rendering: `Page.render` and `Document.render_page` both call into `aspose_pdf.engine.rasterizer`. Most application code never needs to look past `Document` and `Page`. But `aspose_pdf.engine` is an ordinary, importable Python package, and several of the pieces underneath the facade are useful on their own: the rasterizer that turns a page into pixels, the stream-filter codecs that compress and decompress PDF content streams, and the encryption utilities that implement the AES-CBC and RC4 algorithms PDF security handlers rely on. Unlike the main package, `aspose_pdf.engine` submodules are not re-exported from top-level `aspose_pdf` — the one exception is `RasterizedPage`, bridged through `aspose_pdf.visualization` — so everything below is imported by its full dotted path, for example `from aspose_pdf.engine.filters import StreamDecoder`. Aspose.PDF FOSS for Python is a Python package, `aspose-pdf-foss-for-python`, released under the MIT license, requiring Python 3.11 or later. Its top-level module name is `aspose_pdf`. The core package depends only on `cryptography` and `asn1crypto`; optional extras add Pillow-based image decoding, Brotli-based WOFF2 font support, and HarfBuzz-based complex text layout. --- ## Key Features ### Rendering Pages with the Rasterization Engine `Document.render_page(page_index, dpi=..., scale=..., background=..., antialias=...)` and its `Page.render` counterpart both return a `RasterizedPage` — a packed RGB raster produced by the engine's rasterizer. `RasterizedPage` exposes `width`, `height`, and raw `pixels` bytes, plus `get_pixel()` for a single-pixel lookup, `to_png()` / `to_tiff()` for in-memory encoded bytes, and `save()` to write a `.png` or `.tif`/`.tiff` file directly. Working with the object in memory — rather than only saving to disk — is useful when a caller wants to inspect or transform pixels before deciding whether to keep them. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() page.add_text("Rendered by the engine", x=72, y=700, font_size=18) raster = document.render_page(0, dpi=150) print(raster.width, raster.height) corner = raster.get_pixel(0, 0) print("top-left pixel:", corner) with open("page-0.png", "wb") as handle: handle.write(raster.to_png()) raster.save("page-0.tiff") ``` ### The Stream Filter Engine PDF content and object streams are compressed with named filters such as `FlateDecode` and `LZWDecode`. `aspose_pdf.engine.filters.StreamEncoder.encode(data, filters, decode_parms=None)` and `StreamDecoder.decode(data, filters, decode_parms, *, limits=None, max_output_bytes=None)` implement the encode and decode sides of that filter chain — the same codecs the engine uses internally when it writes and reads a document's streams. Both accept a single filter name or a list for chained filters, and `StreamDecoder.decode()` raises `PdfValidationException` on an unrecognized filter name instead of returning silently-wrong bytes. ```python from aspose_pdf.engine.filters import StreamDecoder, StreamEncoder raw = b"Sample content-stream payload.\n" * 40 compressed = StreamEncoder.encode(raw, "FlateDecode") restored = StreamDecoder.decode(compressed, "FlateDecode", None) assert restored == raw print(f"{len(raw)} bytes -> {len(compressed)} bytes with FlateDecode") ``` ### The Encryption Engine `aspose_pdf.engine.encryption.EncryptionUtils` is the static-method utility class `SimplePdf` calls into for every encryption-related operation: `Document.encrypt`, `decrypt()`, and `change_passwords()` all resolve to `EncryptionUtils` calls under the hood. Its methods implement AES-CBC and RC4 encryption directly (`encrypt_aes_cbc`, `decrypt_aes_cbc`, `encrypt_rc4`, `decrypt_rc4`), key derivation for the PDF standard security handler revisions (`compute_owner_key_v4`, `compute_user_key_v4`, `compute_user_owner_keys_v6`), and `generate_file_id()` for the random 16-byte ID new documents need. ```python from aspose_pdf.engine.encryption import EncryptionUtils key = b"0123456789ABCDEF" # 16 bytes -> AES-128 ciphertext = EncryptionUtils.encrypt_aes_cbc(key, b"Reviewer notes: approved") plaintext = EncryptionUtils.decrypt_aes_cbc(key, ciphertext) assert plaintext == b"Reviewer notes: approved" file_id = EncryptionUtils.generate_file_id() print(file_id.hex()) ``` --- ## Quick Start Install the package, then render a page straight from the engine layer in a single script. ```python from aspose_pdf import Document with Document() as document: page = document.pages.add() page.add_text("Engine-rendered page", x=72, y=740, font_size=20) raster = document.render_page(0, dpi=150) raster.save("engine-render.png") document.save("engine-quickstart.pdf") print("Saved engine-quickstart.pdf and engine-render.png") ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | Yes | Yes | | TIFF | tiff | - | Yes | PDF read and write is Aspose.PDF FOSS for Python's core function — the `Document`/`SimplePdf` engine pair loads and writes PDF documents on every code path in this post. `Document.render_page`, `Page.render`, and `RasterizedPage.to_png()` / `to_tiff()` additionally produce PNG and TIFF raster output; these are page-rasterization outputs rather than document-loading formats. --- ## Open Source & Licensing Aspose.PDF FOSS for Python is released under the MIT license: no usage restrictions, no runtime fees, and no registration requirements for commercial or personal use. Source code is hosted at [github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python), packaged as `aspose-pdf-foss-for-python`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/python/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/python/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/python/) - [API Reference](https://reference.aspose.org/pdf/python/) - [GitHub Repository](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # The generated Compatibility Layer in Aspose.PDF FOSS for Python URL: https://blog.aspose.org/pdf/python/pdf-generated-in-python/ Aspose.PDF FOSS for Python ships an aspose_pdf.generated subpackage with a second Document implementation, standalone form-content and PDF/A helper classes, and re-exported security types. This post explains what each module actually does and how its import paths differ from the main aspose_pdf package. --- Product: Aspose.PDF Platform: python Page Type: index Canonical URL: https://blog.aspose.org/pdf/python/pdf-generated-in-python/ --- # The generated Compatibility Layer in Aspose.PDF FOSS for Python ## Introduction Aspose.PDF FOSS for Python includes an `aspose_pdf.generated` subpackage with four modules: `document.py`, `forms.py`, `pdfa.py`, and `security.py`. None of them are re-exported from the top-level `aspose_pdf` package, so every class in this guide is imported by its full dotted path — `from aspose_pdf.generated.document import Document`, not `from aspose_pdf import Document`. The four modules take two different approaches. `generated.document` and `generated.forms` and `generated.pdfa` each define their own classes: independent implementations that mirror the shape of the main package's `Document`, `UnsignedContent`/`UnsignedContentAbsorber`, and `PdfAValidateOptions`/`PdfAValidationResult` — useful for code written against that mirrored namespace layout, but a real, separate set of classes rather than aliases. `generated.security`, on the other hand, does no reimplementation at all: it imports `CompromiseCheckResult`, `SignaturesCompromiseDetector`, and the validation enums directly from `aspose_pdf.security` and `aspose_pdf.validation` and re-exports them, so both import paths resolve to the identical class object. This guide covers all four, and is explicit about where a `generated` class behaves differently from its main-package counterpart of the same name — `Document` and `UnsignedContentAbsorber` both exist in two places with two different implementations, which is exactly the kind of thing that is easy to get wrong when importing by name alone. Aspose.PDF FOSS for Python is a Python package, `aspose-pdf-foss-for-python`, released under the MIT license, requiring Python 3.11 or later. Its top-level module name is `aspose_pdf`; see the Quick Start section below for installation. The core package depends only on `cryptography` and `asn1crypto`; optional extras add Pillow-based image decoding, Brotli-based WOFF2 font support, and HarfBuzz-based complex text layout. --- ## Key Features ### A Second Document Implementation `aspose_pdf.generated.document.Document` implements the same core lifecycle as the main `aspose_pdf.Document` — `load_from()`, `save()`, `encrypt()`/`decrypt()`/`change_passwords()`, `optimize()`/`optimize_resources()`, `repair()`, `flatten()`, and `validate()`/`check()` — on top of the same `aspose_pdf.engine.simple_pdf.SimplePdf` engine. It mirrors a subset of the main `Document`: it has no `pages.add()`-style page authoring, no `form`/`outlines`/`attachments`, and no `render_page()`. Because the class name collides with the main package's `Document`, import it under an alias when both are needed in the same module. ```python from aspose_pdf import Document from aspose_pdf.generated.document import Document as CompatDocument with Document() as document: document.pages.add() document.save("source.pdf") compat = CompatDocument() compat.load_from("source.pdf") print(compat.page_count, compat.is_encrypted) compat.optimize(compress_images=True) compat.save("optimized.pdf", overwrite=True) compat.dispose() ``` ### Packaging Unsigned Content `aspose_pdf.generated.forms.UnsignedContentAbsorber` and `UnsignedContent` provide a container for unsigned form fields, pages, and annotations. This is different from the top-level `aspose_pdf.UnsignedContentAbsorber(document)`, which takes a real `Document` and filters its `form_fields`/`annotations` for items whose `is_signed`/`signed` attribute is falsy. The `generated.forms` version takes no document at all — `extract()` simply packages whatever `pages`, `form_fields`, and `annotations` you pass it as keyword arguments into an `UnsignedContent` instance, which is useful when the unsigned items were already collected elsewhere and just need the shared container and its `add_page()`/`remove_page()`-style mutators. ```python from aspose_pdf.generated.forms import UnsignedContentAbsorber absorber = UnsignedContentAbsorber() content = absorber.extract( form_fields=["signature_field", "initials_field"], annotations=["review_stamp"], ) print(absorber.has_extracted(), content.form_fields, content.annotations) content.add_page("page-1") absorber.reset() print(absorber.get_extracted()) ``` ### PDF/A Validation Options and Results `aspose_pdf.generated.pdfa.PdfAValidateOptions` collects validation settings and input sources; `PdfAValidationResult` collects the outcome. `PdfAValidateOptions.add_input()` checks a string path with `Path.exists()` before accepting it and raises `PdfIOException` if the file is missing, so a caller finds out about a bad input path immediately rather than at validation time. ```python from aspose_pdf import Document from aspose_pdf.exceptions import PdfIOException from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResult with Document() as document: document.pages.add() document.save("candidate.pdf") options = PdfAValidateOptions() options.set_option("pdfa_version", "PDF/A-2b") options.add_input("candidate.pdf") print(options.get_options(), options.inputs) try: options.add_input("missing.pdf") except PdfIOException as error: print(f"rejected: {error}") result = PdfAValidationResult() result.add_error("Missing /OutputIntent for PDF/A-2b") print(result.is_valid, result.to_dict()) ``` ### Re-exported Security and Validation Types `aspose_pdf.generated.security` imports `CompromiseCheckResult` and `SignaturesCompromiseDetector` straight from `aspose_pdf.security`, and `CertificationLevel`, `RevocationStatus`, `TrustStatus`, `ValidationMethod`, `ValidationMode`, `ValidationOptions`, `ValidationResult`, and `ValidationStatus` from `aspose_pdf.validation`. Unlike `Document` and `UnsignedContentAbsorber`, there is no independent reimplementation here — both import paths return the same object. ```python from aspose_pdf.generated.security import SignaturesCompromiseDetector from aspose_pdf.security import SignaturesCompromiseDetector as CanonicalDetector assert SignaturesCompromiseDetector is CanonicalDetector detector = SignaturesCompromiseDetector(document=None) result = detector.check() print(result.compromised, result.reasons) ``` --- ## Quick Start Install the package, then build a document with the main `Document`, save it, and run it past the `generated.pdfa` options and result objects. ```python from aspose_pdf import Document from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResult with Document() as document: page = document.pages.add() page.add_text("PDF/A candidate", x=72, y=740, font_size=20) document.save("candidate.pdf") options = PdfAValidateOptions() options.set_option("pdfa_version", "PDF/A-2b") options.add_input("candidate.pdf") result = PdfAValidationResult() if not options.inputs: result.add_error("No inputs registered") print(result.to_dict()) ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | Yes | Yes | PDF read and write is Aspose.PDF FOSS for Python's core function. Every class in this guide — the main `Document`, the `generated.document.Document` mirror, and the PDF/A helpers — operates on PDF input and output through the shared `SimplePdf` engine; `aspose_pdf.generated` changes which class you import, not what file format is being processed. --- ## Open Source & Licensing Aspose.PDF FOSS for Python is released under the MIT license: no usage restrictions, no runtime fees, and no registration requirements for commercial or personal use. Source code is hosted at [github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python), packaged as `aspose-pdf-foss-for-python`. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/python/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/python/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/python/) - [API Reference](https://reference.aspose.org/pdf/python/) - [GitHub Repository](https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python) ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.PDF FOSS for TypeScript URL: https://blog.aspose.org/pdf/typescript/ --- Product: Aspose.PDF Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/pdf/typescript/ --- # Aspose.PDF FOSS for TypeScript Articles and tutorials for Aspose.PDF FOSS for TypeScript. Covers PDF creation, document and page management, format conversion, annotations, AcroForm fields, and encryption using the MIT-licensed, zero-dependency TypeScript library. ## Related Resources - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) ## Related Topics - [Introducing Aspose.PDF FOSS for TypeScript](https://blog.aspose.org/pdf/typescript/introducing-pdf-foss-typescript/) - [A Deeper Look at Annotations in Aspose.PDF FOSS for TypeScript](https://blog.aspose.org/pdf/typescript/pdf-annotations-in-typescript/) - [Converting and Validating PDFs in Aspose.PDF FOSS for TypeScript](https://blog.aspose.org/pdf/typescript/pdf-conversion-in-typescript/) - [Core Document and Page APIs in Aspose.PDF FOSS for TypeScript](https://blog.aspose.org/pdf/typescript/pdf-core-api-typescript/) --- # Introducing Aspose.PDF FOSS for TypeScript URL: https://blog.aspose.org/pdf/typescript/introducing-pdf-foss-typescript/ Aspose.PDF FOSS for TypeScript is a free, MIT-licensed, zero-dependency Node.js library for creating, editing, converting, annotating, and securing PDF documents. It covers document and page management, format conversion, annotations, AcroForm fields, and encryption through the Document and Page classes. --- Product: Aspose.PDF Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/pdf/typescript/introducing-pdf-foss-typescript/ --- # Introducing Aspose.PDF FOSS for TypeScript ## Introduction Aspose.PDF FOSS for TypeScript is a new open-source library for working with PDF documents from Node.js code. It is released under the MIT license and ships as the `@asposefoss/pdf` package, requiring only Node.js (>=22) at runtime — there are no other runtime dependencies. The library is organized around the `Document` and `Page` classes. `Document.OpenFile()` and `Document.Open()` load a PDF from disk or in-memory bytes, and `Document.New()` starts a blank document; each page in `doc.Pages` exposes methods for adding text, images, annotations, and AcroForm fields, as well as converting itself to other formats. From there, the API covers splitting, merging, and reordering pages, converting documents to HTML, Markdown, DOCX, SVG, and raster images, adding and flattening annotations, building interactive forms, and encrypting, signing, or redacting the result. This release is for developers who need PDF processing inside a Node.js or TypeScript codebase without a commercial license: document assembly pipelines, publishing tools that render PDFs to web-ready formats, form-filling automation, and services that need to redact or encrypt sensitive PDFs before distribution. The project is currently at version 0.1.0 and under active early-stage development, so APIs and feature coverage may evolve before a stable release. --- ## What's Included ### Document and Page Management `Document.OpenFile()` / `Document.Open()` load a PDF from disk or an in-memory `Uint8Array`; `Document.New()` starts a blank document. Pages can be split into separate documents with `Document.Split()`, extracted with `Document.ExtractPages()`, merged with `Document.Merge()`, or appended to an existing document with `Document.Append()`. `Document.WriteTo()` writes the result back out, optionally compressed. ```typescript import { Document } from '@asposefoss/pdf'; // Open from disk (or Document.Open(uint8array) for in-memory data) const doc = Document.OpenFile('input.pdf'); // Inspect and edit pages const pages = doc.Pages; console.log(pages.length); pages[0].Rotate = 90; doc.RemovePage(2); // 1-based page number doc.Reorder([3, 1, 2]); // Save doc.WriteTo('output.pdf'); // or: const bytes = doc.Save(); ``` ### Format Conversion Whole documents render to HTML with `Document.ToHtml()` and to GitHub-flavored Markdown with `Document.ToMarkdown()`. Individual pages render to standalone SVG with `Page.ToSvg()` or raster PNG bytes with `Page.ToImage()`. `Document.ToDocx()` / `Page.ToDocx()` produce reflowed or fixed-layout `.docx` output. ```typescript import { Document } from '@asposefoss/pdf'; const doc = Document.OpenFile('in.pdf'); const png = doc.Pages[0].ToImage({ scale: 2 }); // Uint8Array of PNG bytes @144 DPI const html = doc.ToHtml(); // standalone semantic HTML, all pages const md = doc.ToMarkdown(); // GFM Markdown, all pages const docx = doc.ToDocx(); // .docx bytes, reflowed, images in the package ``` ### Annotations Each `Page` exposes annotation methods directly: `Page.AddHighlight()`, `Page.AddUnderline()`, `Page.AddSquiggly()`, and `Page.AddStrikeOut()` add text markup; `Page.AddTextNote()`, `Page.AddFreeText()`, and `Page.AddStamp()` add sticky notes, free-standing text, and rubber-stamp annotations. Typed subtypes such as `MarkupAnnotation` and `StampAnnotation` expose a `Flatten()` method to bake the annotation into page content. ### AcroForms The `Form` class builds interactive fields directly: `AddTextField()`, `AddCheckbox()`, `AddRadioGroup()`, `AddComboBox()`, `AddListBox()`, and `AddPushButton()` each return a typed `Field` subclass. Calling `SetStyle()` or `GenerateAppearance()` on a field refreshes its rendered appearance, and `Document.FlattenForm()` bakes every field's current value into static page content. ```typescript function addFormFields(doc: Document, page: Page): void { const form = doc.Form; const pageNum = page.Number; // Text field form.AddTextField({ page: pageNum, rect: [200, 670, 450, 690], name: 'FullName', value: 'Alice Sample', }); // Checkbox form.AddCheckbox({ page: pageNum, rect: [200, 630, 218, 648], name: 'Subscribe', checked: true, }); } ``` ### Security and Redaction `Document.WriteTo()` accepts an `encrypt` option supporting AES-128, AES-256, or RC4, with a separate user and owner password and granular `Permissions`. Sensitive regions or matched text can be permanently removed with `Document.Redact()`, `Document.RedactText()`, and `Page.ApplyRedactions()`, configured through `RedactOptions`. ```typescript import { Document } from '@asposefoss/pdf'; const doc = Document.OpenFile('in.pdf'); doc.WriteTo('locked.pdf', { encrypt: { userPassword: 'open-me', // required to open (default '') ownerPassword: 'full-rights', // default: same as userPassword algorithm: 'aes256', // 'aes256' (default) | 'aes128' | 'rc4' permissions: { copying: false, modifying: false }, encryptMetadata: true, }, }); ``` --- ## Quick Start Install the package, then open an existing PDF, edit its pages and metadata, and save the result: ```typescript import { Document } from '@asposefoss/pdf'; // Open from disk (or Document.Open(uint8array) for in-memory data) const doc = Document.OpenFile('input.pdf'); // Inspect and edit pages const pages = doc.Pages; console.log(pages.length); pages[0].Rotate = 90; doc.RemovePage(2); // 1-based page number doc.Reorder([3, 1, 2]); // Metadata doc.SetMetadata({ title: 'Report', author: 'Jane', custom: { Dept: 'R&D' } }); // Save doc.WriteTo('output.pdf'); // or: const bytes = doc.Save(); doc.WriteTo('small.pdf', { compressed: true }); // xref stream + object streams ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | ✓ | ✓ | | Markdown | md | ✓ | ✓ | | SVG | svg | ✓ | ✓ | | TIFF | tiff | ✓ | ✓ | | DOCX | docx | — | ✓ | | HTML | html | — | ✓ | | PNG | png | — | ✓ | | EPUB | epub | — | ✓ | --- ## Open Source & Licensing Aspose.PDF FOSS for TypeScript is released under the MIT license, with source published on GitHub. There is no evaluation watermark, usage limit, or separate license file to manage, and the library may be used in commercial products without royalties. The package is currently at version 0.1.0, reflecting active early-stage development. Node.js (>=22) is the only runtime requirement, and the package has no other third-party dependencies. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/typescript/) - [API Reference](https://reference.aspose.org/pdf/typescript/) ## Related Resources - [Aspose.PDF Enterprise Product Family](https://products.aspose.com/pdf/) - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # A Deeper Look at Annotations in Aspose.PDF FOSS for TypeScript URL: https://blog.aspose.org/pdf/typescript/pdf-annotations-in-typescript/ A closer look at the annotation types in Aspose.PDF FOSS for TypeScript: markup, notes, shapes and freehand ink, link actions, and searching annotation content — beyond the highlight-and-sticky-note basics. --- Product: Aspose.PDF Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/pdf/typescript/pdf-annotations-in-typescript/ --- # A Deeper Look at Annotations in Aspose.PDF FOSS for TypeScript ## Introduction The [introductory post](/pdf/typescript/introducing-pdf-foss-typescript/) covers annotations briefly: highlights, underlines, sticky notes, and stamps, added through `Page.AddHighlight()`, `Page.AddUnderline()`, and similar methods. That is a small slice of what a `Page` actually supports — the annotation gallery in this library covers markup, freehand shapes, links with real navigation and form-submission actions, and searching, all reachable directly from `Page`. This post goes through the rest of that surface: the shape and freehand annotation methods, what a `Link` annotation's action can actually do, and the two different ways to search annotation content depending on whether the text you're looking for lives in the annotation's appearance or its `/Contents` comment. Every annotation method returns a typed handle scoped to the annotation it just created, and every annotation on a page is readable afterward through `page.Annotations`. --- ## What's Included ### Markup Annotations `Page.AddHighlight()`, `Page.AddUnderline()`, `Page.AddSquiggly()`, and `Page.AddStrikeOut()` all take the same shape of options — a set of quad points marking the text region and an optional color — and all four return a `MarkupAnnotation`. The quad points are typically derived from a text search or from a known text rectangle. ```typescript const markup = (body: [number, number, number, number], sample: string, add: (quads: number[]) => void): void => { const yMid = (body[1] + body[3]) / 2 - 6; const textRect: [number, number, number, number] = [body[0] + 4, yMid, body[2] - 4, yMid + 16]; page.AddText(sample, textRect[0], textRect[1], { fontSize: 12 }); add(rectToQuads(textRect)); }; markup(cardBody, 'Highlight this phrase', (quads) => page.AddHighlight({ quads, color: [1, 1, 0], contents: 'Yellow highlight' })); markup(cardBody, 'Underline this phrase', (quads) => page.AddUnderline({ quads, color: [0, 0, 1] })); markup(cardBody, 'Squiggle this phrase', (quads) => page.AddSquiggly({ quads, color: [1, 0.5, 0] })); markup(cardBody, 'Strike this phrase out', (quads) => page.AddStrikeOut({ quads, color: [1, 0, 0] })); ``` ### Notes and Free-Standing Text `Page.AddTextNote()` adds a classic sticky-note icon that opens a comment popup when clicked, returning a `TextAnnotation`. `Page.AddFreeText()` instead draws its text directly on the page inside a bordered box, with its own font size, alignment, and fill color — useful for callouts that should be visible without opening anything. ```typescript page.AddTextNote({ rect: [x, y, x + 20, y + 20], icon: 'Note', author: 'Reviewer', contents: 'This is a sticky-note annotation.', }); page.AddFreeText({ rect: [220, 60, 520, 96], contents: 'FreeText sample', fontSize: 10, align: 'center', fill: [1, 1, 0.8], width: 1, }); ``` ### Shapes and Freehand Ink `Page.AddSquare()` and `Page.AddCircle()` draw a bordered rectangle or ellipse, each with an optional interior fill. `Page.AddLine()` draws a straight line between two points, with independently selectable arrowhead styles (`startEnding`/`endEnding`, e.g. `'OpenArrow'`/`'ClosedArrow'`) at each end. `Page.AddPolygon()` and `Page.AddPolyline()` draw closed and open multi-point shapes from a flat list of coordinates, and `Page.AddInk()` records one or more freehand pen strokes as `paths` of point lists. ```typescript page.AddSquare({ rect: [50, 400, 130, 435], color: [0.8, 0, 0], fill: [1, 1, 0.5], width: 2 }); page.AddCircle({ rect: [150, 400, 230, 435], color: [0, 0.5, 0], width: 2 }); page.AddLine({ line: [260, 417, 420, 417], color: [0, 0, 0.7], width: 2, startEnding: 'OpenArrow', endEnding: 'ClosedArrow', }); const stroke: number[] = []; [-8, 6, -4, 10, -2, 8, -6].forEach((dy, i) => stroke.push(440 + i * 12, 417 + dy)); page.AddInk({ paths: [stroke], color: [0.6, 0, 0.6], width: 2 }); ``` ### Links and Their Actions `Page.AddLink()` returns a `LinkAnnotation` whose `action` decides what happens on click: `{ type: 'uri', uri: '...' }` opens an external URL, `{ type: 'goto', page: N }` jumps to a page within the same document, and `{ type: 'submit', url: '...', format: 'html' }` submits the current form-field values to an endpoint. An out-of-range `goto` page number or a malformed action object is rejected at creation time rather than silently accepted. ```typescript const uriLink = page.AddLink({ rect: [10, 10, 100, 30], action: { type: 'uri', uri: 'https://example.com' }, }); const gotoLink = page.AddLink({ rect: [10, 40, 100, 60], action: { type: 'goto', page: 2 }, }); const submitLink = page.AddLink({ rect: [10, 70, 100, 90], action: { type: 'submit', url: 'https://example.com/post', format: 'html' }, }); // page.AddLink({ rect: [...], action: { type: 'goto', page: 99 } }) throws RangeError // when 99 is out of range for the document. ``` ### Searching Annotation Content Two different methods search annotation text, and they are deliberately disjoint: `Page.SearchAnnotations()` searches the text an annotation's own appearance *draws* — the visible label on a `FreeText` or stamp, for example — while `Page.SearchAnnotationText()` searches the text carried in the annotation's `/Contents` entry, such as a sticky note's comment body. A match in one does not imply a match in the other. ```typescript page.SearchAnnotations('bravo'); // finds it if the annotation's drawn appearance contains it page.SearchAnnotationText('bravo'); // finds it if the annotation's /Contents comment contains it ``` Annotations no longer needed can be removed directly with `Page.RemoveAnnotation()`, passing either the annotation handle or its underlying dictionary. --- ## Quick Start Install the package, then add a highlight, a link, and a sticky note to an existing page: ```typescript import { Document } from '@asposefoss/pdf'; const doc = Document.OpenFile('input.pdf'); const page = doc.Pages[0]; page.AddHighlight({ quads: [72, 700, 300, 700, 72, 715, 300, 715], color: [1, 1, 0] }); page.AddLink({ rect: [72, 670, 200, 690], action: { type: 'uri', uri: 'https://example.com' }, }); page.AddTextNote({ rect: [320, 670, 340, 690], icon: 'Note', author: 'Reviewer', contents: 'Please double-check this figure.', }); doc.WriteTo('annotated.pdf'); ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | ✓ | ✓ | | Markdown | md | ✓ | ✓ | | SVG | svg | ✓ | ✓ | | TIFF | tiff | ✓ | ✓ | | DOCX | docx | — | ✓ | | HTML | html | — | ✓ | | PNG | png | — | ✓ | | EPUB | epub | — | ✓ | --- ## Open Source & Licensing Aspose.PDF FOSS for TypeScript is released under the MIT license, with source published on GitHub. There is no evaluation watermark, usage limit, or separate license file to manage, and the library may be used in commercial products without royalties. The package is currently at version 0.1.0, reflecting active early-stage development. Node.js (>=22) is the only runtime requirement, and the package has no other third-party dependencies. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/typescript/) - [API Reference](https://reference.aspose.org/pdf/typescript/) ## Related Resources - [Aspose.PDF Enterprise Product Family](https://products.aspose.com/pdf/) - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Converting and Validating PDFs in Aspose.PDF FOSS for TypeScript URL: https://blog.aspose.org/pdf/typescript/pdf-conversion-in-typescript/ A closer look at conversion in Aspose.PDF FOSS for TypeScript beyond the basics: semantic versus fixed-layout HTML export, reflowed versus fixed-geometry DOCX, and validating and converting toward the PDF/A, PDF/X, and PDF/UA standards. --- Product: Aspose.PDF Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/pdf/typescript/pdf-conversion-in-typescript/ --- # Converting and Validating PDFs in Aspose.PDF FOSS for TypeScript ## Introduction The [introductory post](/pdf/typescript/introducing-pdf-foss-typescript/) shows the basic shape of conversion: `Document.ToHtml()`, `Document.ToMarkdown()`, and `Document.ToDocx()`, each called with no arguments to get a reasonable default. Every one of those methods takes an options object that changes what actually comes out — semantic markup versus a pixel-faithful copy, a reflowable Word document versus one that reproduces each page's exact layout. This post covers those options, plus a conversion direction the introduction does not touch at all: validating a document against the PDF/A, PDF/X, and PDF/UA standards and remediating it toward compliance with `Document.ConvertToPdfA()` and its siblings. --- ## What's Included ### HTML Export: Semantic vs Fixed `Document.ToHtml()` called with no options walks the document's structure tree and emits reflowable markup — headings and paragraphs that read naturally in a browser at any width. That mode depends on the document being tagged first (`Document.CreateStructTree()` or an equivalent tagging pass); without a structure tree, the export falls back to a plain heuristic body instead of true semantic markup. Passing `{ mode: 'fixed', fonts: 'embed' }` switches to a different rendering strategy entirely: each page becomes positioned SVG and absolutely-placed text, with every embeddable font program inlined as a base64 WOFF `@font-face` so the page looks the same without the reader having the fonts installed. ```typescript // Semantic mode reflows from the structure tree, so this must run after the // tagging pass: ToHtml falls back to a heuristic body when GetStructTree() is // null, and the export loses its heading structure silently. const semantic = doc.ToHtml(); const fixed = doc.ToHtml({ mode: 'fixed', fonts: 'embed' }); ``` The two outputs serve different purposes: semantic HTML is what you want for reading or re-publishing content on the web, and fixed HTML is what you want when the page's exact visual layout has to survive unmodified in a browser. ### Word and Vector Exports `Document.ToDocx()` called with no options produces a reflowed `.docx`: paragraphs and images that a word processor can rewrap and edit like a normal document. Passing `{ mode: 'textbox' }` instead keeps each page's own geometry, placing content in fixed text boxes rather than letting it reflow — closer to a faithful visual copy than an editable document. `Page.ToSvg()` renders a single page to a standalone `` string, useful when a vector, resolution-independent copy of one page is needed rather than a raster image. ```typescript import { Document } from '@asposefoss/pdf'; const doc = Document.OpenFile('in.pdf'); const svg = doc.Pages[0].ToSvg(); // standalone string const docx = doc.ToDocx(); // .docx bytes, reflowed, images in the package const fixed = doc.ToDocx({ mode: 'textbox' }); // .docx keeping each page's own geometry ``` ### Validating and Converting to PDF/A, PDF/X, and PDF/UA `Document.ValidatePdfA()`, `Document.ValidatePdfX()`, and `Document.ValidatePdfUa()` each check the document against a curated, machine-checkable subset of the corresponding standard — PDF/A (ISO 19005) for long-term archival, PDF/X (ISO 15930) for print production, and PDF/UA (ISO 14289-1) for accessibility — and return a `ValidationReport` with a `Passed` flag summarizing the result. `Document.ConvertToPdfA()` (and the equivalent `ConvertToPdfX()`/`ConvertToPdfUa()`) attempts to remediate the document toward that level, then re-validates, returning a `ConversionReport` that lists which actions it actually applied and which issues remain unresolved. ```typescript import { Document } from '@asposefoss/pdf'; const doc = Document.OpenFile('in.pdf'); const pdfa = doc.ValidatePdfA('2b'); console.log(`validate: PDF/A-2b ${pdfa.Passed ? 'passes' : 'fails'}`); // Conversion runs against a copy: the live document is still saved // unconverted, so ConvertToPdfA must never touch it directly. const pages = doc.Pages; const allPages: number[] = []; for (let i = 1; i string const html = doc.ToHtml(); // reflowable HTML (falls back without a structure tree) const docx = doc.ToDocx(); // .docx bytes, reflowed, images in the package // fs.writeFileSync('page1.svg', svg); // fs.writeFileSync('out.html', html); // fs.writeFileSync('out.docx', docx); ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | ✓ | ✓ | | Markdown | md | ✓ | ✓ | | SVG | svg | ✓ | ✓ | | TIFF | tiff | ✓ | ✓ | | DOCX | docx | — | ✓ | | HTML | html | — | ✓ | | PNG | png | — | ✓ | | EPUB | epub | — | ✓ | --- ## Open Source & Licensing Aspose.PDF FOSS for TypeScript is released under the MIT license, with source published on GitHub. There is no evaluation watermark, usage limit, or separate license file to manage, and the library may be used in commercial products without royalties. The package is currently at version 0.1.0, reflecting active early-stage development. Node.js (>=22) is the only runtime requirement, and the package has no other third-party dependencies. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/typescript/) - [API Reference](https://reference.aspose.org/pdf/typescript/) ## Related Resources - [Aspose.PDF Enterprise Product Family](https://products.aspose.com/pdf/) - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Core Document and Page APIs in Aspose.PDF FOSS for TypeScript URL: https://blog.aspose.org/pdf/typescript/pdf-core-api-typescript/ A tour of the Document and Page classes at the core of Aspose.PDF FOSS for TypeScript: assembling and reorganizing documents, building pages from scratch, bookmarks and navigation, and structured-text tagging for accessibility. --- Product: Aspose.PDF Platform: typescript Page Type: index Canonical URL: https://blog.aspose.org/pdf/typescript/pdf-core-api-typescript/ --- # Core Document and Page APIs in Aspose.PDF FOSS for TypeScript ## Introduction Every capability in Aspose.PDF FOSS for TypeScript is reached through two classes: `Document` and `Page`. `Document` owns the page collection and everything document-scoped — metadata, bookmarks, page labels, and save/load — while each `Page` in `doc.Pages` owns everything scoped to that one page: content, annotations, and form fields. Once those two classes are familiar, the rest of the library's surface — conversion, annotations, forms, security — is really just more methods on the same two objects. This post is a closer look at the parts of that core surface the [introductory post](/pdf/typescript/introducing-pdf-foss-typescript/) only mentions in passing: assembling documents out of other documents, building pages from nothing, adding a bookmark tree for navigation, and tagging content for accessibility. All four are plain method calls — no separate module to import, no extra dependency beyond the `@asposefoss/pdf` package itself. These are the operations that come up once a PDF pipeline moves past "open one file, change it, save it": combining reports from several sources into one document, generating pages programmatically instead of starting from a template, and making the output navigable and accessible rather than just visually correct. --- ## What's Included ### Assembling and Reorganizing Documents `Document.Split()` breaks a document into one new single-page `Document` per page, in page order. `Document.ExtractPages()` copies a given set of 1-based page numbers into a new self-contained `Document`, in the order given — the same page can be repeated. Pages from one document can also be copied into another: `Document.Append()` copies every page of a source document onto the end of the target, and `Document.InsertPage()` copies a single page across documents at a specific 1-based position. ```typescript import { Document } from '@asposefoss/pdf'; const report = Document.OpenFile('report.pdf'); const parts = report.Split(); // one Document per page const chapter = report.ExtractPages([3, 4, 5]); // subset (1-based, repeats allowed) as a new Document const cover = Document.OpenFile('cover.pdf'); report.InsertPage(1, cover.Pages[0]); // copy a single page across documents report.Append(chapter); // copy chapter's pages onto report report.WriteTo('assembled.pdf'); ``` Several documents can also be combined into one in a single call with `Document.Merge()`, which builds a new `Document` from copies of every page of every document passed to it, in order. ### Building Pages From Scratch `Document.New()` creates a document from nothing: zero pages when a format is omitted, or one blank page of the given `PageFormat` when one is passed. Additional blank pages come from `Document.AddPage()`, which also accepts a `PageFormat` (or an existing `Page` to copy the size of). Text is drawn onto a page with `Page.AddText()`, positioned at an (x, y) point in PDF user space. ```typescript import { Document, PageFormat } from '@asposefoss/pdf'; const doc = Document.New(PageFormat.A4); // one blank A4 page doc.Pages[0].AddText('Hello', 72, 720, { fontSize: 14 }); doc.AddPage(PageFormat.A4.landscape()); // append more as you go doc.WriteTo('scratch.pdf'); ``` ### Bookmarks and Document Navigation The document outline (the bookmark panel most PDF readers show alongside the page) is read with `Document.GetOutlines()` and replaced wholesale with `Document.SetOutlines()`, each working with a tree of `OutlineItem` values. Each `OutlineItem` carries a `Title`, a `Dest` destination, and optionally `Children` for nested entries, plus display hints like `Open` (expanded by default) and `Bold`. ```typescript import { Document, OutlineItem } from '@asposefoss/pdf'; const items: OutlineItem[] = [ { Title: 'Introduction', Dest: { name: 'intro' } }, { Title: 'Chapters', Open: true, Children: [ { Title: 'Chapter 1', Dest: { name: 'ch1' } }, { Title: 'Chapter 2', Dest: { name: 'ch2' } }, ], }, ]; doc.SetOutlines(items); ``` Destinations named this way (`{ name: 'intro' }`) resolve through the document's named-destination table, which `Document.GetNamedDestinations()` and `Document.SetNamedDestination()` manage directly when a bookmark needs to point at a destination that isn't tied to page content. ### Structured Text and Accessibility Tagging `Document.GetStructTree()` returns the document's logical structure tree (or `null` when the document isn't tagged), and `Document.CreateStructTree()` builds one, marking the document Tagged. Once a structure tree exists, `Page.GetStructuredText()` returns the page's text as `TextBlock` values — positioned fragments already grouped into lines and paragraph-like blocks — which is the input a hand-tagging pass works from: walking the blocks, deciding which ones are headings versus body text, and appending the corresponding elements to the tree. ```typescript function handTagPage(doc: Document, page: Page, heading: string): void { const root = doc.GetStructTree(); if (!root) throw new Error('handTagPage: the document is not tagged yet'); for (const block of page.GetStructuredText()) { const text = block.text.trim(); if (text.length === 0) continue; const el = root.Append(text.startsWith(heading) ? 'H2' : 'P'); el.MarkContent(page, block.quad); } } ``` A tagged structure tree is what downstream features build on: semantic HTML export reflows from it instead of falling back to a plain heuristic layout, and `Document.ValidatePdfUa()` checks the document against a subset of the PDF/UA accessibility standard that depends on tagging being present. --- ## Quick Start Install the package, then open a document, pull out and recombine a subset of its pages, and save the result: ```typescript import { Document } from '@asposefoss/pdf'; const doc = Document.OpenFile('report.pdf'); const chapter = doc.ExtractPages([3, 4, 5]); // subset (1-based, repeats allowed) as a new Document const cover = Document.OpenFile('cover.pdf'); doc.InsertPage(1, cover.Pages[0]); // copy a single page across documents doc.Append(chapter); // copy chapter's pages onto doc doc.WriteTo('assembled.pdf'); ``` --- ## Supported Formats | Format | Extension | Read | Write | |---|---|---|---| | PDF | pdf | ✓ | ✓ | | Markdown | md | ✓ | ✓ | | SVG | svg | ✓ | ✓ | | TIFF | tiff | ✓ | ✓ | | DOCX | docx | — | ✓ | | HTML | html | — | ✓ | | PNG | png | — | ✓ | | EPUB | epub | — | ✓ | --- ## Open Source & Licensing Aspose.PDF FOSS for TypeScript is released under the MIT license, with source published on GitHub. There is no evaluation watermark, usage limit, or separate license file to manage, and the library may be used in commercial products without royalties. The package is currently at version 0.1.0, reflecting active early-stage development. Node.js (>=22) is the only runtime requirement, and the package has no other third-party dependencies. --- ## Getting Started - [Getting Started](https://docs.aspose.org/pdf/typescript/getting-started/) - [Developer Guide](https://docs.aspose.org/pdf/typescript/developer-guide/) - [KB Articles](https://kb.aspose.org/pdf/typescript/) - [API Reference](https://reference.aspose.org/pdf/typescript/) ## Related Resources - [Aspose.PDF Enterprise Product Family](https://products.aspose.com/pdf/) - [Aspose.PDF — Enterprise Blog](https://blog.aspose.com/) --- # Search URL: https://blog.aspose.org/search search --- Product: search Page Type: blog Canonical URL: https://blog.aspose.org/search --- # Search --- # Aspose.Slides FOSS for C++ URL: https://blog.aspose.org/slides/cpp/ --- Product: Aspose.Slides Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/slides/cpp/ --- # Aspose.Slides FOSS for C++ ## Related Topics - [Introducing Aspose.Slides FOSS for C++](https://blog.aspose.org/slides/cpp/cpp-powerpoint-pptx-library/) - [Aspose.Slides FOSS for C++ — Key Features](https://blog.aspose.org/slides/cpp/cpp-pptx-slides-shapes-tables/) - [Core API Overview for Aspose.Slides FOSS C++](https://blog.aspose.org/slides/cpp/slides-core-api-cpp/) - [Visual Effects in PowerPoint Presentations with C++](https://blog.aspose.org/slides/cpp/slides-visual-effects-cpp/) --- # Introducing Aspose.Slides FOSS for C++ URL: https://blog.aspose.org/slides/cpp/cpp-powerpoint-pptx-library/ Aspose.Slides FOSS for C++ is a free, open-source library for creating and editing PowerPoint presentations without Microsoft Office. MIT licensed, native C++, no API key required. --- Product: Aspose.Slides Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/slides/cpp/cpp-powerpoint-pptx-library/ --- # Introducing Aspose.Slides FOSS for C++ ## Introduction Aspose.Slides FOSS for C++ is now available: a free, MIT-licensed library for creating, reading, and editing PowerPoint `.pptx` files in native C++, with no dependency on Microsoft Office or any proprietary runtime. The library is designed for developers who need to generate or manipulate presentation files programmatically: automating slide decks from data, extracting text and metadata from uploaded PPTX files, building presentation-based reporting pipelines, or embedding presentation creation into desktop and server applications. Because `aspose_slides_foss` is built with CMake, it compiles and deploys on Windows, macOS, and Linux. ## Key Features - **Full round-trip PPTX support**: Open any `.pptx` file, modify its content, and save it back without losing unknown XML parts that the library does not yet understand. - **Slides management**: Add, remove, and iterate slides using `prs.slides()`; the presentation starts with one blank slide after constructing a `Presentation`. - **AutoShapes, Tables, and Connectors**: Insert shapes via `slide.shapes().add_auto_shape()`, tabular data via `slide.shapes().add_table()`, and visual connectors between shapes via `slide.shapes().add_connector()`. - **Rich text formatting**: Format text at character level with `PortionFormat`: font size, bold, italic, underline, and ARGB color via `FillType::SOLID` and `ColorFormat`. - **Fill types**: Apply `FillType::SOLID`, `FillType::GRADIENT`, `FillType::PATTERN`, or `FillType::PICTURE` fills to any shape. - **Visual effects**: Outer shadow, glow, soft edge, blur, reflection, and inner shadow via `shape.effect_format()`. - **3D formatting**: Bevel, camera, light rig, material, and extrusion depth via `shape.three_d_format()`. - **Speaker notes**: Attach notes text to each slide via `notes_slide_manager().add_notes_slide()`. - **Threaded comments**: Add comments with author metadata and slide position. - **Embedded images**: Embed from file path, memory buffer, or stream. - **Document properties**: Read and write core, app, and custom properties. ## Getting Started Add the library via CMake. A C++20 compiler is required. ```cmake include(FetchContent) FetchContent_Declare( aspose_slides_foss GIT_REPOSITORY https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Cpp.git GIT_TAG main ) FetchContent_MakeAvailable(aspose_slides_foss) target_link_libraries(your_target PRIVATE aspose_slides_foss) ``` Create your first presentation with a shape and save it: ```cpp #include #include #include #include #include #include #include #include int main() { using namespace Aspose::Slides::Foss; Presentation prs; auto& slide = prs.slides()[0]; auto& shape = slide.shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 400, 120 ); shape.text_frame()->set_text("Hello from Aspose.Slides FOSS!"); prs.save("hello.pptx", SaveFormat::PPTX); return 0; } ``` The `Presentation` destructor releases all internal resources automatically when it goes out of scope. ## Text Formatting Example ```cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 500, 150 ); shape.text_frame()->set_text("Bold heading in corporate blue"); auto& fmt = shape.text_frame()->paragraphs()[0].portions()[0].portion_format(); fmt.set_font_height(28); fmt.set_font_bold(NullableBool::TRUE); fmt.fill_format().set_fill_type(FillType::SOLID); fmt.fill_format().solid_fill_color().set_color(Color::from_argb(255, 0, 70, 127)); prs.save("formatted.pptx", SaveFormat::PPTX); return 0; } ``` ## Current Limitations The following areas are not available in this edition: - Charts, SmartArt, and OLE objects - Animations and slide transitions - Export to PDF, HTML, SVG, or image formats - Hyperlinks, action settings, VBA macros, and digital signatures Unknown XML parts encountered during load are preserved verbatim on save, so PPTX files produced by other tools round-trip safely. ## See Also - [Installation Guide](https://docs.aspose.org/slides/cpp/getting-started/installation/) - [Features Overview](https://docs.aspose.org/slides/cpp/developer-guide/features/) - [API Reference](https://reference.aspose.org/slides/cpp/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Slides for C++ — Enterprise Product](https://products.aspose.com/slides/cpp/) --- # Aspose.Slides FOSS for C++ — Key Features URL: https://blog.aspose.org/slides/cpp/cpp-pptx-slides-shapes-tables/ Explore the key features of Aspose.Slides FOSS for C++: creating and saving PPTX presentations, managing slides, adding shapes with fill and text, and applying visual effects — free, MIT-licensed, no Office required. --- Product: Aspose.Slides Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/slides/cpp/cpp-pptx-slides-shapes-tables/ --- # Aspose.Slides FOSS for C++ — Key Features ## Introduction Aspose.Slides FOSS for C++ (`aspose_slides_foss`) is a free, MIT-licensed library for creating and editing PowerPoint `.pptx` files in native C++. It runs on Windows, macOS, and Linux with no dependency on Microsoft Office. This article walks through the key features available in the current release. --- ## Key Features ### Presentation Loading and Saving `Presentation` is the root object. Construct it with no arguments to create a new file or pass a file path to load an existing one. Call `save()` with a path and `SaveFormat` to write the output: ```cpp #include #include using namespace Aspose::Slides::Foss; // Create new Presentation prs; prs.save("output.pptx", SaveFormat::PPTX); // Load and save Presentation prs2("existing.pptx"); prs2.save("copy.pptx", SaveFormat::PPTX); ``` ### Slide Management The `slides()` method returns the slide collection. Add slides with `add_empty_slide()`, remove them with `remove()`, and access existing slides by index: ```cpp #include #include #include using namespace Aspose::Slides::Foss; Presentation prs; auto& slide = prs.slides()[0]; // First slide (created automatically) // Add a second slide using the first master/layout auto& layout = prs.masters()[0].layout_slides()[0]; auto& newSlide = prs.slides().add_empty_slide(layout); prs.save("two_slides.pptx", SaveFormat::PPTX); ``` ### AutoShape Insertion and Text Add shapes using `slide.shapes().add_auto_shape()`. Access the text frame via `shape.text_frame()` to set text content: ```cpp #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; Presentation prs; auto& slide = prs.slides()[0]; auto& shape = slide.shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 300, 100 ); shape.text_frame()->set_text("Hello from Aspose.Slides FOSS"); prs.save("shape_demo.pptx", SaveFormat::PPTX); ``` ### Solid Fills Apply `FillType::SOLID` with an ARGB color to any shape: ```cpp #include #include #include #include #include #include using namespace Aspose::Slides::Foss; Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 100, 100, 400, 200 ); shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(0xFF, 0x46, 0x82, 0xB4); prs.save("solid_fill.pptx", SaveFormat::PPTX); ``` ### Visual Effects Apply outer shadows, glow, and soft-edge effects via `shape.effect_format()`: ```cpp #include #include #include #include #include #include using namespace Aspose::Slides::Foss; Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 100, 100, 300, 150 ); auto& ef = shape.effect_format(); ef.enable_outer_shadow_effect(); ef.outer_shadow_effect().set_blur_radius(8); ef.outer_shadow_effect().set_distance(6); ef.outer_shadow_effect().set_direction(45); prs.save("shadow.pptx", SaveFormat::PPTX); ``` --- ## Quick Start Add the library via CMake (C++20 compiler required): ```cmake include(FetchContent) FetchContent_Declare( aspose_slides_foss GIT_REPOSITORY https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Cpp.git GIT_TAG main ) FetchContent_MakeAvailable(aspose_slides_foss) target_link_libraries(your_target PRIVATE aspose_slides_foss) ``` ```cpp #include #include #include #include #include int main() { using namespace Aspose::Slides::Foss; Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 400, 150 ); shape.text_frame()->set_text("My first slide"); prs.save("first.pptx", SaveFormat::PPTX); return 0; } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PPTX | `.pptx` | — | ✓ | --- ## Open Source & Licensing Aspose.Slides FOSS for C++ is released under the MIT License. Build from source via CMake. Commercial use, redistribution, and modification are all permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/slides/cpp/getting-started/) - [Developer Guide](https://docs.aspose.org/slides/cpp/developer-guide/) - [KB Articles](https://kb.aspose.org/slides/cpp/) - [API Reference](https://reference.aspose.org/slides/cpp/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Core API Overview for Aspose.Slides FOSS C++ URL: https://blog.aspose.org/slides/cpp/slides-core-api-cpp/ Explore the core API of Aspose.Slides FOSS for C++. Learn how to create presentations, add shapes and tables, apply formatting, and export to PPTX using this open-source, MIT-licensed library. --- Product: Aspose.Slides Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/slides/cpp/slides-core-api-cpp/ --- # Core API Overview for Aspose.Slides FOSS C++ ## Introduction Aspose.Slides FOSS for C++ (`aspose_slides_foss`) is a free, open-source C++20 library for creating and manipulating PowerPoint presentations programmatically. Built entirely in native C++ with no external runtime dependencies beyond CMake 3.20+, it gives developers full control over PPTX files without requiring Microsoft Office or any proprietary software. The library is released under the MIT license, making it suitable for both commercial and non-commercial projects. The public API lives in the `Aspose::Slides::Foss` namespace and provides a rich object model covering presentations, slides, shapes, tables, text frames, document properties, comments, and PPTX export. This post walks through the core API surface: the classes and methods you will use most often when building, formatting, and saving presentations. --- ## What's Included ### Presentation and Slide Management The `Presentation` class is the entry point. Creating a new instance gives you a default slide that is immediately ready for content. You access slides through the `SlideCollection` returned by `slides()`, which supports indexed access, iteration, removal, and reordering. ```cpp #include using namespace Aspose::Slides::Foss; Presentation pres; auto& slide = pres.slides()[0]; // first slide // Work with the slide... pres.save("output.pptx", SaveFormat::PPTX); ``` ### Shapes and AutoShapes Every slide exposes a `ShapeCollection` through its `shapes()` accessor. The collection provides factory methods for adding different shape types: `add_auto_shape` for standard geometry shapes (rectangles, ellipses, triangles), `add_connector` for line connectors, `add_table` for tables, and `add_picture_frame` for images. ```cpp auto& slide = pres.slides()[0]; // Add a rectangle auto& rect = slide.shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 300, 100); // Add an ellipse auto& ellipse = slide.shapes().add_auto_shape( ShapeType::ELLIPSE, 400, 50, 150, 150); // Add a connector between shapes auto& conn = slide.shapes().add_connector( ShapeType::BENT_CONNECTOR3, 0, 0, 1, 1); ``` The `ShapeCollection` also supports `size()`, `remove()`, `remove_at()`, `reorder()`, `index_of()`, and `clear()` for managing shapes after creation. ### Text and Paragraph Formatting Shapes can hold text via `TextFrame`. Use `add_text_frame()` on an `AutoShape` to attach text content, or access the existing frame through `text_frame()`. Text is organized into paragraphs, each containing one or more portions. The `BasePortionFormat` class exposes font styling properties including bold, italic, underline type, capitalization, strikethrough, and font color. ```cpp auto& shape = pres.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 300, 100, false); shape.add_text_frame("Hello, world!"); auto text = shape.text_frame()->text(); // "Hello, world!" ``` ### Fill, Gradient, and Visual Effects Each shape provides a `FillFormat` accessible via `fill_format()`. You can set solid fills, gradient fills, or pattern fills through the `set_fill_type()` method. Gradient fills are configured through the `GradientFormat` object, which supports linear angles, gradient shape, and color stops via `GradientStopCollection`. ```cpp auto& shape = slide.shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 300, 150); shape.fill_format().set_fill_type(FillType::GRADIENT); auto& gf = shape.fill_format().gradient_format(); gf.set_gradient_shape(GradientShape::LINEAR); gf.set_linear_gradient_angle(45); gf.gradient_stops().add(0.0f, Color::blue); gf.gradient_stops().add(1.0f, Color::red); ``` The `EffectFormat` class (accessed via `effect_format()`) adds glow, outer shadow, and soft edge effects. Each effect is enabled with a dedicated method (`enable_glow_effect()`, `enable_outer_shadow_effect()`, `enable_soft_edge_effect()`) and configured through its returned object. ### Tables Tables are created with `add_table()` on the shape collection. You supply column widths and row heights as vectors. The returned `Table` object exposes `rows()` and `columns()` collections, and individual `Cell` objects support text content via `TextFrame`. ```cpp std::vector col_widths = {100, 150, 200}; std::vector row_heights = {40, 40, 40}; auto& table = slide.shapes().add_table( 50, 50, col_widths, row_heights); // table.rows().size() == 3 // table.columns().size() == 3 ``` ### Document Properties and Comments The `DocumentProperties` class lets you set metadata such as title, author, subject, keywords, category, revision number, and timestamps. Access it through the presentation object. Comments are managed through `CommentAuthorCollection` and `CommentCollection`. You add authors with `add_author()`, then attach comments to specific slides at specific coordinates. ```cpp Presentation pres; auto& author = pres.comment_authors().add_author("Alice", "A"); auto& slide = pres.slides()[0]; auto& comment = author.comments().add_comment( "Review note", slide, PointF(2.0f, 3.0f), now); ``` --- ## Quick Start ### Building from Source The library requires CMake 3.20+ and a C++20-capable compiler. Clone the repository and build: ```bash git clone https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Cpp.git cd Aspose.Slides-FOSS-for-Cpp cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build ``` ### Minimal Example ```cpp #include using namespace Aspose::Slides::Foss; int main() { Presentation pres; auto& slide = pres.slides()[0]; // Add a shape with text auto& shape = slide.shapes().add_auto_shape( ShapeType::RECTANGLE, 50, 50, 300, 100, false); shape.add_text_frame("Hello from Aspose.Slides FOSS!"); // Apply a solid fill shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::blue); // Save pres.save("hello.pptx", SaveFormat::PPTX); return 0; } ``` --- ## Supported Formats The `SaveFormat` enum defines all export targets. The following formats are confirmed in the source code: | Format | Extension | Read | Write | |--------|-----------|------|-------| | PPTX | .pptx | -- | Yes | | PPT | .ppt | -- | Planned | | PPSX | .ppsx | -- | Planned | | PPTM | .pptm | -- | Planned | | PPSM | .ppsm | -- | Planned | | POTX | .potx | -- | Planned | | POTM | .potm | -- | Planned | | POT | .pot | -- | Planned | | PPS | .pps | -- | Planned | | ODP | .odp | -- | Planned | | OTP | .otp | -- | Planned | | FODP | .fodp | -- | Planned | | PDF | .pdf | -- | Planned | | XPS | .xps | -- | Planned | | HTML | .html | -- | Planned | | HTML5 | .html | -- | Planned | | TIFF | .tiff | -- | Planned | | GIF | .gif | -- | Planned | | SWF | .swf | -- | Planned | | MD | .md | -- | Planned | | XML | .xml | -- | Planned | **Note:** Currently only PPTX export is implemented. Other format values exist in the `SaveFormat` enum for forward compatibility but are not yet functional. The `save()` method always produces PPTX output regardless of the format parameter. --- ## Open Source & Licensing Aspose.Slides FOSS for C++ is released under the MIT license. You can use it freely in personal projects, commercial applications, and redistributed libraries. There are no API keys, watermarks, or usage limits. The full source code is available on GitHub at [https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Cpp](https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Cpp). --- ## Getting Started Ready to integrate Aspose.Slides FOSS into your C++ project? Here are the key resources: - **Documentation**: [https://docs.aspose.org/slides/cpp/](https://docs.aspose.org/slides/cpp/) for developer guides, tutorials, and conceptual overviews. - **Knowledge Base**: [https://kb.aspose.org/slides/cpp/](https://kb.aspose.org/slides/cpp/) for FAQs and how-to articles covering common tasks. - **API Reference**: [https://reference.aspose.org/slides/cpp/](https://reference.aspose.org/slides/cpp/) for class-by-class documentation of the full public API. ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Visual Effects in PowerPoint Presentations with C++ URL: https://blog.aspose.org/slides/cpp/slides-visual-effects-cpp/ Use Aspose.Slides FOSS for C++ to apply solid and gradient fills, outer shadows, glow effects, and 3D bevels to PowerPoint shapes. No Office required. --- Product: Aspose.Slides Platform: cpp Page Type: index Canonical URL: https://blog.aspose.org/slides/cpp/slides-visual-effects-cpp/ --- # Visual Effects in PowerPoint Presentations with C++ ## Introduction Aspose.Slides FOSS for C++ lets you apply professional-quality visual effects to PowerPoint shapes in native C++, with no Microsoft Office and no API keys required. This guide shows how to use the fill system (solid and gradient), 2D effects (drop shadows and glow), and 3D formatting (bevels, camera presets, and materials) to produce polished presentations entirely in code. ## Quick Start Add the library to your CMake project (see [Getting Started](#getting-started) below), then apply a solid blue fill to a rounded rectangle and save it as PPTX: ```cpp #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::ROUND_CORNER_RECTANGLE, 100, 100, 400, 150 ); shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::from_argb(255, 30, 80, 180)); prs.save("out.pptx", SaveFormat::PPTX); return 0; } ``` --- ## The Fill System Every shape has a `fill_format()` that controls how its interior is painted. The four fill types demonstrated below cover the core of PowerPoint's design palette. ### Solid Fill `FillType::SOLID` paints the shape interior with a flat color at a given opacity. Call `solid_fill_color().set_color()` with an ARGB value to set the color; the alpha channel controls transparency: ```cpp #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::ROUND_CORNER_RECTANGLE, 100, 100, 400, 150 ); shape.text_frame()->set_text("Solid Fill"); shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::from_argb(255, 30, 80, 180)); prs.save("solid.pptx", SaveFormat::PPTX); return 0; } ``` ### Linear Gradient Fill `FillType::GRADIENT` blends between two or more colors across the shape. Add stops at position 0.0 (start) and 1.0 (end), and set `set_linear_gradient_angle()` to control the direction: ```cpp #include #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 100, 100, 400, 150 ); auto& ff = shape.fill_format(); ff.set_fill_type(FillType::GRADIENT); auto& gf = ff.gradient_format(); gf.set_gradient_shape(GradientShape::LINEAR); gf.set_linear_gradient_angle(90); // top-to-bottom gf.gradient_stops().add(0.0f, Color::from_argb(255, 30, 80, 180)); // top: blue gf.gradient_stops().add(1.0f, Color::from_argb(255, 0, 200, 160)); // bottom: teal prs.save("gradient.pptx", SaveFormat::PPTX); return 0; } ``` --- ## 2D Visual Effects ### Outer Drop Shadow Call `EffectFormat::enable_outer_shadow_effect()` to attach a drop shadow to a shape. Configure `set_blur_radius()` (softness), `set_direction()` (angle in degrees), and `set_distance()` (offset from the shape edge): ```cpp #include #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::ROUND_CORNER_RECTANGLE, 100, 100, 350, 150 ); shape.text_frame()->set_text("Drop Shadow"); shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::white); auto& ef = shape.effect_format(); ef.enable_outer_shadow_effect(); auto* shadow = ef.outer_shadow_effect(); shadow->set_blur_radius(12); shadow->set_direction(315); // upper-left shadow->set_distance(8); shadow->shadow_color().set_color(Color::from_argb(100, 0, 0, 0)); prs.save("shadow.pptx", SaveFormat::PPTX); return 0; } ``` ### Glow Effect Call `EffectFormat::enable_glow_effect()` to surround a shape with a colored halo. Set `set_radius()` to control how far the glow extends from the edge (in points), and set the glow color separately from the shape fill: ```cpp #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::ELLIPSE, 150, 100, 250, 250 ); shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::from_argb(255, 20, 60, 140)); auto& ef = shape.effect_format(); ef.enable_glow_effect(); auto* glow = ef.glow_effect(); glow->set_radius(20); glow->color().set_color(Color::from_argb(200, 0, 180, 255)); prs.save("glow.pptx", SaveFormat::PPTX); return 0; } ``` --- ## 3D Formatting ### Bevel and Material The `three_d_format()` method gives any flat shape a three-dimensional appearance. Combine a bevel with a camera preset and a material for the richest result: ```cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::RECTANGLE, 150, 150, 300, 130 ); shape.text_frame()->set_text("Metal Button"); // Blue solid fill shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::from_argb(255, 20, 70, 160)); // 3D bevel + camera + light + material auto& tdf = shape.three_d_format(); tdf.bevel_top().set_bevel_type(BevelPresetType::CIRCLE); tdf.bevel_top().set_width(10); tdf.bevel_top().set_height(5); tdf.camera().set_camera_type(CameraPresetType::PERSPECTIVE_ABOVE); tdf.light_rig().set_light_type(LightRigPresetType::BALANCED); tdf.light_rig().set_direction(LightingDirection::TOP); tdf.set_material(MaterialPresetType::METAL); tdf.set_depth(20); prs.save("metal-button.pptx", SaveFormat::PPTX); return 0; } ``` --- ## Combining Effects on the Same Shape Shadow and 3D formatting can coexist on a single shape, enabling polished "card" designs: ```cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Aspose::Slides::Foss; using namespace Aspose::Slides::Foss::Drawing; int main() { Presentation prs; auto& shape = prs.slides()[0].shapes().add_auto_shape( ShapeType::ROUND_CORNER_RECTANGLE, 120, 120, 360, 150 ); shape.text_frame()->set_text("Premium Card"); // Fill shape.fill_format().set_fill_type(FillType::SOLID); shape.fill_format().solid_fill_color().set_color(Color::from_argb(255, 30, 80, 180)); // 3D bevel auto& tdf = shape.three_d_format(); tdf.bevel_top().set_bevel_type(BevelPresetType::CIRCLE); tdf.bevel_top().set_width(8); tdf.camera().set_camera_type(CameraPresetType::PERSPECTIVE_ABOVE); tdf.set_material(MaterialPresetType::PLASTIC); // Drop shadow auto& ef = shape.effect_format(); ef.enable_outer_shadow_effect(); auto* shadow = ef.outer_shadow_effect(); shadow->set_blur_radius(14); shadow->set_direction(270); shadow->set_distance(8); shadow->shadow_color().set_color(Color::from_argb(70, 0, 0, 0)); prs.save("premium-card.pptx", SaveFormat::PPTX); return 0; } ``` --- ## Getting Started Add Aspose.Slides FOSS for C++ to your CMake project using `FetchContent`. After the `FetchContent_MakeAvailable` call, link your target against `aspose_slides_foss`: ```cmake include(FetchContent) FetchContent_Declare( aspose_slides_foss GIT_REPOSITORY https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Cpp.git GIT_TAG main ) FetchContent_MakeAvailable(aspose_slides_foss) target_link_libraries(your_target PRIVATE aspose_slides_foss) ``` No Microsoft Office installation or license keys are required; all processing runs in the local process with no external dependencies. --- ## Related Resources - [EffectFormat and ThreeDFormat reference](https://reference.aspose.org/slides/cpp/EffectFormat/) - [FillFormat reference](https://reference.aspose.org/slides/cpp/FillFormat/) - [Getting Started](https://docs.aspose.org/slides/cpp/getting-started/) - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Slides FOSS for Java URL: https://blog.aspose.org/slides/java/ --- Product: Aspose.Slides Platform: java Page Type: index Canonical URL: https://blog.aspose.org/slides/java/ --- # Aspose.Slides FOSS for Java ## Related Topics - [Introducing Aspose.Slides FOSS for Java](https://blog.aspose.org/slides/java/java-powerpoint-pptx-library/) - [Aspose.Slides FOSS for Java — Key Features](https://blog.aspose.org/slides/java/java-pptx-slides-shapes-text/) - [Core API of Aspose.Slides FOSS for Java](https://blog.aspose.org/slides/java/slides-core-api-java/) - [Visual Effects in PowerPoint Presentations with Java](https://blog.aspose.org/slides/java/slides-visual-effects-java/) --- # Introducing Aspose.Slides FOSS for Java URL: https://blog.aspose.org/slides/java/java-powerpoint-pptx-library/ Aspose.Slides FOSS for Java is a free, open-source library for creating and editing PowerPoint presentations without Microsoft Office. MIT licensed, pure Java, no API key required. --- Product: Aspose.Slides Platform: java Page Type: index Canonical URL: https://blog.aspose.org/slides/java/java-powerpoint-pptx-library/ --- # Introducing Aspose.Slides FOSS for Java ## Introduction Aspose.Slides FOSS for Java is now available on Maven Central: a free, MIT-licensed library for creating, reading, and editing PowerPoint `.pptx` files entirely in Java, with no dependency on Microsoft Office or any proprietary runtime. The library is designed for developers who need to generate or manipulate presentation files programmatically: automating slide decks from data, extracting text and metadata from uploaded PPTX files, building presentation-based reporting pipelines, or embedding presentation creation into Spring Boot applications. Because `aspose-slides-foss` is pure Java, it deploys identically on Windows, macOS, Linux, and Docker containers. ## Key Features - **Full round-trip PPTX support**: Open any `.pptx` file, modify its content, and save it back without losing unknown XML parts that the library does not yet understand. - **Slides management**: Add, remove, and iterate slides using `prs.getSlides()`; the presentation starts with one blank slide after `new Presentation()`. - **AutoShapes, Tables, and Connectors**: Insert shapes via `slide.getShapes().addAutoShape()`, tabular data via `slide.getShapes().addTable()`, and visual connectors between shapes via `slide.getShapes().addConnector()`. - **Rich text formatting**: Format text at character level with `PortionFormat`: font size, bold, italic, underline, and ARGB color via `FillType.SOLID` and `ColorFormat`. - **Fill types**: Apply `FillType.SOLID`, `GRADIENT`, `PATTERN`, or `PICTURE` fills to any shape. - **Visual effects**: Outer shadow, glow, soft edge, blur, reflection, and inner shadow via `shape.getEffectFormat()`. - **3D formatting**: Bevel, camera, light rig, material, and extrusion depth via `shape.getThreeDFormat()`. - **Speaker notes**: Attach notes text to each slide via `getNotesSlideManager().addNotesSlide()`. - **Threaded comments**: Add comments with author metadata and slide position. - **Embedded images**: Embed from file path, bytes, or `InputStream`. - **Document properties**: Read and write core, app, and custom properties. ## Getting Started Add the Maven dependency. Java 21 or later is required. Create your first presentation with a shape and save it: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.ITextFrame; import org.aspose.slides.foss.IPortionFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.NullableBool; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; public class HelloSlides { public static void main(String[] args) { try (Presentation prs = new Presentation()) { ISlide slide = prs.getSlides().get(0); IAutoShape shape = slide.getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 50, 400, 120 ); shape.addTextFrame("Hello from Aspose.Slides FOSS!"); prs.save("hello.pptx"); } } } ``` Always use `Presentation` inside a try-with-resources block; this ensures all internal resources are released when the block exits. ## Text Formatting Example ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.ITextFrame; import org.aspose.slides.foss.IPortionFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.NullableBool; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { IAutoShape shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 50, 500, 150 ); ITextFrame tf = shape.addTextFrame("Bold heading in corporate blue"); IPortionFormat fmt = tf.getParagraphs().get(0).getPortions().get(0).getPortionFormat(); fmt.setFontHeight(28); fmt.setFontBold(NullableBool.TRUE); fmt.getFillFormat().setFillType(FillType.SOLID); fmt.getFillFormat().getSolidFillColor().setColor(new Color(0, 70, 127)); prs.save("formatted.pptx"); } ``` ## Current Limitations The following areas throw `UnsupportedOperationException` in this release: - Charts, SmartArt, and OLE objects - Animations and slide transitions - Export to PDF, HTML, SVG, or image formats - Hyperlinks, action settings, VBA macros, and digital signatures Unknown XML parts encountered during load are preserved verbatim on save, so PPTX files produced by other tools round-trip safely. ## See Also - [Installation Guide](https://docs.aspose.org/slides/java/getting-started/installation/) - [Features Overview](https://docs.aspose.org/slides/java/developer-guide/features/) - [API Reference](https://reference.aspose.org/slides/java/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Slides for Java — Enterprise Product](https://products.aspose.com/slides/java/) --- # Aspose.Slides FOSS for Java — Key Features URL: https://blog.aspose.org/slides/java/java-pptx-slides-shapes-text/ Explore the key features of Aspose.Slides FOSS for Java: creating and saving PPTX presentations, managing slides, adding shapes with fill and text, and applying visual effects — free, MIT-licensed, no Office required. --- Product: Aspose.Slides Platform: java Page Type: index Canonical URL: https://blog.aspose.org/slides/java/java-pptx-slides-shapes-text/ --- # Aspose.Slides FOSS for Java — Key Features ## Introduction Aspose.Slides FOSS for Java (`aspose-slides-foss` on Maven Central) is a free, MIT-licensed library for creating and editing PowerPoint `.pptx` files entirely in Java. It runs on Windows, macOS, Linux, and Docker containers with no dependency on Microsoft Office. This article walks through the key features available in version 1.0.0. --- ## Key Features ### Presentation Loading and Saving `Presentation` is the root object. Construct it with no arguments to create a new file or pass a file path to load an existing one. Call `save()` with a file path to write the output. Use try-with-resources to ensure all internal resources are released: ```java import org.aspose.slides.foss.Presentation; // Create new try (Presentation prs = new Presentation()) { prs.save("output.pptx"); } // Load and save try (Presentation prs2 = new Presentation("existing.pptx")) { prs2.save("copy.pptx"); } ``` ### Slide Management The `getSlides()` method returns the slide collection. Add slides with `addEmptySlide()`, remove them with `remove()`, and access existing slides by index: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.ILayoutSlide; try (Presentation prs = new Presentation()) { ISlide slide = prs.getSlides().get(0); // First slide (created automatically) // Add a second slide using the first master/layout ILayoutSlide layout = prs.getMasters().get(0).getLayoutSlides().get(0); ISlide newSlide = prs.getSlides().addEmptySlide(layout); prs.save("two_slides.pptx"); } ``` ### AutoShape Insertion and Text Add shapes using `slide.getShapes().addAutoShape()`. Capture the returned `ITextFrame` from the shape to set text content and apply character formatting: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.ITextFrame; import org.aspose.slides.foss.IPortionFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.NullableBool; try (Presentation prs = new Presentation()) { ISlide slide = prs.getSlides().get(0); IAutoShape shape = slide.getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 50, 300, 100 ); ITextFrame tf = shape.addTextFrame("Hello from Aspose.Slides FOSS"); IPortionFormat fmt = tf.getParagraphs().get(0).getPortions().get(0).getPortionFormat(); fmt.setFontHeight(24); fmt.setFontBold(NullableBool.TRUE); prs.save("shape_demo.pptx"); } ``` ### Solid and Gradient Fills Apply `FillType.SOLID` with an RGB color or `FillType.GRADIENT` for multi-stop fills: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { IAutoShape shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.RECTANGLE, 100, 100, 400, 200 ); shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(new Color(70, 130, 180)); prs.save("solid_fill.pptx"); } ``` ### Visual Effects Apply outer shadows, glow, and soft-edge effects via `shape.getEffectFormat()`: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { IAutoShape shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.RECTANGLE, 100, 100, 300, 150 ); IEffectFormat ef = shape.getEffectFormat(); ef.enableOuterShadowEffect(); ef.getOuterShadowEffect().setBlurRadius(8); ef.getOuterShadowEffect().setDistance(6); ef.getOuterShadowEffect().setDirection(45); ef.getOuterShadowEffect().getShadowColor().setColor(Color.fromArgb(128, 0, 0, 0)); prs.save("shadow.pptx"); } ``` --- ## Quick Start Add the Maven dependency (Java 21 or later required): ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.ShapeType; try (Presentation prs = new Presentation()) { IAutoShape shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 50, 400, 150 ); shape.addTextFrame("My first slide"); prs.save("first.pptx"); } ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PPTX | `.pptx` | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Slides FOSS for Java is released under the MIT License. Install from Maven Central as `aspose-slides-foss`. Commercial use, redistribution, and modification are all permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/slides/java/getting-started/) - [Developer Guide](https://docs.aspose.org/slides/java/developer-guide/) - [KB Articles](https://kb.aspose.org/slides/java/) - [API Reference](https://reference.aspose.org/slides/java/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Core API of Aspose.Slides FOSS for Java URL: https://blog.aspose.org/slides/java/slides-core-api-java/ Explore the core API of Aspose.Slides FOSS for Java. Learn how to create presentations, manage slides, add shapes and text, build tables, and save to PPTX — all with a free, MIT-licensed library. --- Product: Aspose.Slides Platform: java Page Type: index Canonical URL: https://blog.aspose.org/slides/java/slides-core-api-java/ --- # Core API of Aspose.Slides FOSS for Java ## Introduction Aspose.Slides FOSS for Java is a free, open-source library that lets Java developers create and manipulate PowerPoint presentations without any dependency on Microsoft Office. The library ships under the `org.aspose.slides.foss` package and targets Java 21 and above. The project is released under the MIT license, so you can use it in both personal and commercial projects at no cost and with no API key. It provides classes for slides, shapes, text, tables, images, comments, and document properties, backed by direct manipulation of the Office Open XML package format. With 273 classes, over 2,600 methods, and 42 enumerations, the core API covers the building blocks you need to automate presentation workflows in any Java application. --- ## What's Included ### Presentation Lifecycle The `Presentation` class is the entry point for every operation. You can create a blank presentation and save the result to disk or to an `OutputStream` in a variety of formats. The class implements `AutoCloseable`, so it works naturally with try-with-resources blocks. ```java import org.aspose.slides.foss.*; import org.aspose.slides.foss.export.SaveFormat; try (Presentation pres = new Presentation()) { // A new presentation starts with one blank slide System.out.println("Slides: " + pres.getSlides().size()); pres.save("output.pptx", SaveFormat.PPTX); } ``` ### Slide Management `SlideCollection` lets you add blank slides with `addEmptySlide()`, duplicate existing slides with `addClone()`, insert slides at a specific index with `insertEmptySlide()`, remove slides by reference or index, and iterate over the collection. ```java try (Presentation pres = new Presentation()) { var layout = pres.getLayoutSlides().get(0); pres.getSlides().addEmptySlide(layout); pres.getSlides().addClone(pres.getSlides().get(0)); System.out.println("Total slides: " + pres.getSlides().size()); } ``` ### Shapes and AutoShapes The `AutoShape` class represents the most common drawable object on a slide. You create shapes through `IShapeCollection.addAutoShape()`, specifying a `ShapeType` constant (such as `ShapeType.RECTANGLE`) and position coordinates. Each `AutoShape` exposes a `TextFrame` for text content and a `FillFormat` for visual styling. ```java try (Presentation pres = new Presentation()) { var slide = pres.getSlides().get(0); IAutoShape shape = slide.getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 50, 300, 100, false); ITextFrame tf = shape.addTextFrame("Hello from Aspose.Slides FOSS"); System.out.println(tf.getText()); } ``` ### Text and Paragraphs Rich text is modeled as a hierarchy of `TextFrame`, `ParagraphCollection`, `Paragraph`, `PortionCollection`, and `Portion` objects. You can set plain text on a frame directly with `TextFrame.setText()`, or build multi-run paragraphs by adding individual `Portion` instances with distinct formatting. ```java try (Presentation pres = new Presentation()) { var slide = pres.getSlides().get(0); IAutoShape shape = slide.getShapes() .addAutoShape(ShapeType.RECTANGLE, 50, 50, 400, 100, false); ITextFrame tf = shape.addTextFrame("First run "); Portion extra = new Portion("second run"); tf.getParagraphs().get(0).getPortions().add(extra); System.out.println(tf.getText()); } ``` ### Document Properties The `DocumentProperties` class exposes standard metadata fields such as title, author, subject, keywords, category, and timestamps. Properties are persisted in the PPTX core and extended properties parts and survive round-trip save/reload cycles. ```java try (Presentation pres = new Presentation()) { IDocumentProperties props = pres.getDocumentProperties(); props.setTitle("Quarterly Report"); props.setAuthor("Engineering Team"); pres.save("report.pptx", SaveFormat.PPTX); } ``` ### Comments and Annotations The comment subsystem includes `CommentAuthorCollection` and `CommentCollection`. You can add authors, attach comments to specific slides and positions, and read back existing annotations. Comment data is persisted in the PPTX package's comment parts and survives round-trip save/reload cycles. --- ## Quick Start Add the following Maven dependency to your `pom.xml` to include Aspose.Slides FOSS for Java in your project: Then create and save a presentation: ```java import org.aspose.slides.foss.*; import org.aspose.slides.foss.export.SaveFormat; public class QuickStart { public static void main(String[] args) { try (Presentation pres = new Presentation()) { var slide = pres.getSlides().get(0); // Add a title shape IAutoShape title = slide.getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 30, 600, 60, false); title.addTextFrame("Aspose.Slides FOSS for Java"); // Add a content shape IAutoShape body = slide.getShapes().addAutoShape( ShapeType.RECTANGLE, 50, 120, 600, 300, false); body.addTextFrame( "This presentation was created entirely in Java " + "using a free, open-source library."); pres.save("quick-start.pptx", SaveFormat.PPTX); } } } ``` --- ## Supported Formats The `SaveFormat` enumeration defines every output format the library can write. The table below lists the confirmed entries. | Format | Extension | Write | |--------|-----------|-------| | PPTX | .pptx | Yes | | PPTM | .pptm | Planned | | PPSX | .ppsx | Planned | | PPSM | .ppsm | Planned | | POTX | .potx | Planned | | POTM | .potm | Planned | | ODP | .odp | Planned | | OTP | .otp | Planned | | FODP | .fodp | Planned | | PPT | .ppt | Planned | | PPS | .pps | Planned | | POT | .pot | Planned | | PDF | .pdf | Planned | | XPS | .xps | Planned | | HTML | .html | Planned | | HTML5 | .html | Planned | | SVG | .svg | Planned | | TIFF | .tiff | Planned | | PNG | .png | Planned | | JPEG | .jpeg | Planned | | BMP | .bmp | Planned | | GIF | .gif | Planned | | MD | .md | Planned | **Note:** PPTX export is fully implemented. Other `SaveFormat` enum values (PPT, ODP, PDF, PNG, etc.) are defined for forward compatibility and will be functional in future releases; passing them to `save()` currently produces PPTX output. --- ## Open Source & Licensing Aspose.Slides FOSS for Java is distributed under the MIT license. The full source code is available on GitHub at [Aspose.Slides-FOSS-for-Java](https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Java). You are free to use, modify, and redistribute the library in any project without royalties or license keys. --- ## Getting Started Ready to dive deeper? Here are resources to help you get started: - [Developer Guide](https://docs.aspose.org/slides/java/) -- walkthroughs and tutorials for every feature area - [Knowledge Base](https://kb.aspose.org/slides/java/) -- how-to articles and frequently asked questions - [API Reference](https://reference.aspose.org/slides/java/) -- full class and method documentation ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Visual Effects in PowerPoint Presentations with Java URL: https://blog.aspose.org/slides/java/slides-visual-effects-java/ Use Aspose.Slides FOSS for Java to apply solid and gradient fills, outer shadows, glow effects, and 3D bevels to PowerPoint shapes. No Office required. --- Product: Aspose.Slides Platform: java Page Type: index Canonical URL: https://blog.aspose.org/slides/java/slides-visual-effects-java/ --- # Visual Effects in PowerPoint Presentations with Java ## Introduction Aspose.Slides FOSS for Java lets you apply professional-quality visual effects to PowerPoint shapes entirely in Java, with no Microsoft Office and no API keys required. This guide shows how to use the fill system (solid and gradient), 2D effects (drop shadows and glow), and 3D formatting (bevels, camera presets, and materials) to produce polished presentations from code. ## Quick Start Add the Maven dependency and apply a solid fill to a shape: ```java import org.aspose.slides.foss.*; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var slide = prs.getSlides().get(0); IAutoShape shape = slide.getShapes() .addAutoShape(ShapeType.ROUND_CORNER_RECTANGLE, 100, 100, 400, 150); shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(new Color(30, 80, 180)); prs.save("out.pptx"); } ``` --- ## The Fill System Every shape has a fill format accessed via `getFillFormat()` that controls how its interior is painted. The five fill types cover the full range of PowerPoint's design palette. ### Solid Fill `FillType.SOLID` paints the shape interior with a flat color. Call `getSolidFillColor().setColor()` with an RGB `Color` value to set the hue and optional transparency: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IFillFormat; import org.aspose.slides.foss.IGradientFormat; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.IThreeDFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.GradientShape; import org.aspose.slides.foss.BevelPresetType; import org.aspose.slides.foss.CameraPresetType; import org.aspose.slides.foss.LightRigPresetType; import org.aspose.slides.foss.LightingDirection; import org.aspose.slides.foss.MaterialPresetType; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.ROUND_CORNER_RECTANGLE, 100, 100, 400, 150 ); shape.addTextFrame("Solid Fill"); shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(new Color(30, 80, 180)); prs.save("solid.pptx"); } ``` ### Linear Gradient Fill `FillType.GRADIENT` transitions between two or more colors across the shape. Add stops with `getGradientStops().add()`, set `setGradientShape()` to `LINEAR`, and control the direction with `setLinearGradientAngle()` (90 degrees = top-to-bottom): ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IFillFormat; import org.aspose.slides.foss.IGradientFormat; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.IThreeDFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.GradientShape; import org.aspose.slides.foss.BevelPresetType; import org.aspose.slides.foss.CameraPresetType; import org.aspose.slides.foss.LightRigPresetType; import org.aspose.slides.foss.LightingDirection; import org.aspose.slides.foss.MaterialPresetType; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.RECTANGLE, 100, 100, 400, 150 ); IFillFormat ff = shape.getFillFormat(); ff.setFillType(FillType.GRADIENT); IGradientFormat gf = ff.getGradientFormat(); gf.setGradientShape(GradientShape.LINEAR); gf.setLinearGradientAngle(90); // top-to-bottom gf.getGradientStops().add(0.0f, new Color(30, 80, 180)); // top: blue gf.getGradientStops().add(1.0f, new Color(0, 200, 160)); // bottom: teal prs.save("gradient.pptx"); } ``` --- ## 2D Visual Effects ### Outer Drop Shadow Call `IEffectFormat.enableOuterShadowEffect()` to attach a drop shadow. Configure `setBlurRadius()` (softness), `setDirection()` (angle in degrees), and `setDistance()` (offset from the shape edge): ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IFillFormat; import org.aspose.slides.foss.IGradientFormat; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.IThreeDFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.GradientShape; import org.aspose.slides.foss.BevelPresetType; import org.aspose.slides.foss.CameraPresetType; import org.aspose.slides.foss.LightRigPresetType; import org.aspose.slides.foss.LightingDirection; import org.aspose.slides.foss.MaterialPresetType; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.ROUND_CORNER_RECTANGLE, 100, 100, 350, 150 ); shape.addTextFrame("Drop Shadow"); shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(Color.WHITE); IEffectFormat ef = shape.getEffectFormat(); ef.enableOuterShadowEffect(); ef.getOuterShadowEffect().setBlurRadius(12); ef.getOuterShadowEffect().setDirection(315); // upper-left ef.getOuterShadowEffect().setDistance(8); ef.getOuterShadowEffect().getShadowColor().setColor(new Color(100, 0, 0, 0)); prs.save("shadow.pptx"); } ``` ### Glow Effect Call `IEffectFormat.enableGlowEffect()` to surround a shape with a colored halo. Set `setRadius()` to control how far the glow extends from the edge (in points), then configure the glow color independently from the shape fill: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IFillFormat; import org.aspose.slides.foss.IGradientFormat; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.IThreeDFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.GradientShape; import org.aspose.slides.foss.BevelPresetType; import org.aspose.slides.foss.CameraPresetType; import org.aspose.slides.foss.LightRigPresetType; import org.aspose.slides.foss.LightingDirection; import org.aspose.slides.foss.MaterialPresetType; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.ELLIPSE, 150, 100, 250, 250 ); shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(new Color(20, 60, 140)); IEffectFormat ef = shape.getEffectFormat(); ef.enableGlowEffect(); ef.getGlowEffect().setRadius(20); ef.getGlowEffect().getColor().setColor(new Color(200, 0, 180, 255)); prs.save("glow.pptx"); } ``` --- ## 3D Formatting ### Bevel and Material The `getThreeDFormat()` method gives any flat shape a three-dimensional appearance. Combine a bevel with a camera preset and a material for the richest result: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IFillFormat; import org.aspose.slides.foss.IGradientFormat; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.IThreeDFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.GradientShape; import org.aspose.slides.foss.BevelPresetType; import org.aspose.slides.foss.CameraPresetType; import org.aspose.slides.foss.LightRigPresetType; import org.aspose.slides.foss.LightingDirection; import org.aspose.slides.foss.MaterialPresetType; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.RECTANGLE, 150, 150, 300, 130 ); shape.addTextFrame("Metal Button"); // Blue solid fill shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(new Color(20, 70, 160)); // 3D bevel + camera + light + material IThreeDFormat tdf = shape.getThreeDFormat(); tdf.getBevelTop().setBevelType(BevelPresetType.CIRCLE); tdf.getBevelTop().setWidth(10); tdf.getBevelTop().setHeight(5); tdf.getCamera().setCameraType(CameraPresetType.PERSPECTIVE_ABOVE); tdf.getLightRig().setLightType(LightRigPresetType.BALANCED); tdf.getLightRig().setDirection(LightingDirection.TOP); tdf.setMaterial(MaterialPresetType.METAL); tdf.setDepth(20); prs.save("metal-button.pptx"); } ``` --- ## Combining Effects on the Same Shape Shadow and 3D formatting can coexist on a single shape, enabling polished "card" designs: ```java import org.aspose.slides.foss.Presentation; import org.aspose.slides.foss.ISlide; import org.aspose.slides.foss.IAutoShape; import org.aspose.slides.foss.IFillFormat; import org.aspose.slides.foss.IGradientFormat; import org.aspose.slides.foss.IEffectFormat; import org.aspose.slides.foss.IThreeDFormat; import org.aspose.slides.foss.ShapeType; import org.aspose.slides.foss.FillType; import org.aspose.slides.foss.GradientShape; import org.aspose.slides.foss.BevelPresetType; import org.aspose.slides.foss.CameraPresetType; import org.aspose.slides.foss.LightRigPresetType; import org.aspose.slides.foss.LightingDirection; import org.aspose.slides.foss.MaterialPresetType; import org.aspose.slides.foss.export.SaveFormat; import org.aspose.slides.foss.drawing.Color; try (Presentation prs = new Presentation()) { var shape = prs.getSlides().get(0).getShapes().addAutoShape( ShapeType.ROUND_CORNER_RECTANGLE, 120, 120, 360, 150 ); shape.addTextFrame("Premium Card"); // Fill shape.getFillFormat().setFillType(FillType.SOLID); shape.getFillFormat().getSolidFillColor().setColor(new Color(30, 80, 180)); // 3D bevel IThreeDFormat tdf = shape.getThreeDFormat(); tdf.getBevelTop().setBevelType(BevelPresetType.CIRCLE); tdf.getBevelTop().setWidth(8); tdf.getCamera().setCameraType(CameraPresetType.PERSPECTIVE_ABOVE); tdf.setMaterial(MaterialPresetType.PLASTIC); // Drop shadow IEffectFormat ef = shape.getEffectFormat(); ef.enableOuterShadowEffect(); ef.getOuterShadowEffect().setBlurRadius(14); ef.getOuterShadowEffect().setDirection(270); ef.getOuterShadowEffect().setDistance(8); ef.getOuterShadowEffect().getShadowColor().setColor(new Color(70, 0, 0, 0)); prs.save("premium-card.pptx"); } ``` --- ## Getting Started Add the following Maven dependency to your `pom.xml` to include Aspose.Slides FOSS for Java in your project: No Microsoft Office installation or license keys are required; all processing runs in the local JVM with no external dependencies. --- ## Related Resources - [EffectFormat and ThreeDFormat reference](https://reference.aspose.org/slides/java/EffectFormat/) - [FillFormat reference](https://reference.aspose.org/slides/java/FillFormat/) - [Getting Started](https://docs.aspose.org/slides/java/getting-started/) - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Slides FOSS for .NET URL: https://blog.aspose.org/slides/net/ --- Product: Aspose.Slides Platform: net Page Type: index Canonical URL: https://blog.aspose.org/slides/net/ --- # Aspose.Slides FOSS for .NET ## Related Topics - [Introducing Aspose.Slides FOSS for .NET](https://blog.aspose.org/slides/net/dotnet-powerpoint-pptx-library/) - [Aspose.Slides FOSS for .NET — Key Features](https://blog.aspose.org/slides/net/dotnet-pptx-slides-shapes-api/) - [Presentation Management with Aspose.Slides FOSS for .NET](https://blog.aspose.org/slides/net/slides-presentation-management-net/) - [Visual Effects in PowerPoint Presentations with .NET](https://blog.aspose.org/slides/net/slides-visual-effects-dotnet/) --- # Introducing Aspose.Slides FOSS for .NET URL: https://blog.aspose.org/slides/net/dotnet-powerpoint-pptx-library/ Aspose.Slides FOSS for .NET is a free, open-source library for creating and editing PowerPoint presentations without Microsoft Office. MIT licensed, pure C#, no API key required. --- Product: Aspose.Slides Platform: net Page Type: index Canonical URL: https://blog.aspose.org/slides/net/dotnet-powerpoint-pptx-library/ --- # Introducing Aspose.Slides FOSS for .NET ## Introduction Aspose.Slides FOSS for .NET is now available on NuGet: a free, MIT-licensed library for creating, reading, and editing PowerPoint `.pptx` files entirely in C#, with no dependency on Microsoft Office or any proprietary runtime. The library is designed for developers who need to generate or manipulate presentation files programmatically: automating slide decks from data, extracting text and metadata from uploaded PPTX files, building presentation-based reporting pipelines, or embedding presentation creation into ASP.NET applications. Because `Aspose.Slides.Foss` requires .NET 9.0 or later, it deploys identically on Windows, macOS, Linux, and Docker containers. ## Key Features - **Full round-trip PPTX support**: Open any `.pptx` file, modify its content, and save it back without losing unknown XML parts that the library does not yet understand. - **Slides management**: Add, remove, and iterate slides using `prs.Slides`; the presentation starts with one blank slide after `new Presentation()`. - **AutoShapes, Tables, and Connectors**: Insert shapes via `slide.Shapes.AddAutoShape()`, tabular data via `slide.Shapes.AddTable()`, and visual connectors between shapes via `slide.Shapes.AddConnector()`. - **Rich text formatting**: Format text at character level with `PortionFormat`: font size, bold, italic, underline, and ARGB color via `FillType.Solid` and `ColorFormat`. - **Fill types**: Apply `FillType.Solid`, `Gradient`, `Pattern`, or `Picture` fills to any shape. - **Visual effects**: Outer shadow, glow, soft edge, blur, reflection, and inner shadow via `shape.EffectFormat`. - **3D formatting**: Bevel, camera, light rig, material, and extrusion depth via `shape.ThreeDFormat`. - **Speaker notes**: Attach notes text to each slide via `NotesSlideManager.AddNotesSlide()`. - **Threaded comments**: Add comments with author metadata and slide position. - **Embedded images**: Embed from file path, bytes, or `Stream`. - **Document properties**: Read and write core, app, and custom properties. ## Getting Started Install from NuGet. .NET 9.0 or later is required. Create your first presentation with a shape and save it: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Export; using var prs = new Presentation(); var slide = prs.Slides[0]; var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 400, 120); shape.AddTextFrame("Hello from Aspose.Slides FOSS!"); prs.Save("hello.pptx", SaveFormat.Pptx); ``` Always use `Presentation` inside a `using` block; this ensures all internal resources are released when the block exits. ## Text Formatting Example ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Drawing; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 500, 150); var tf = shape.AddTextFrame("Bold heading in corporate blue"); var fmt = tf.Paragraphs[0].Portions[0].PortionFormat; fmt.FontHeight = 28; fmt.FontBold = NullableBool.True; fmt.FillFormat.FillType = FillType.Solid; fmt.FillFormat.SolidFillColor.Color = Color.FromArgb(255, 0, 70, 127); prs.Save("formatted.pptx", SaveFormat.Pptx); ``` ## Current Limitations The following areas are not supported in this release: - Charts, SmartArt, and OLE objects - Animations and slide transitions - Export to PDF, HTML, SVG, or image formats - Hyperlinks, action settings, VBA macros, and digital signatures Unknown XML parts encountered during load are preserved verbatim on save, so PPTX files produced by other tools round-trip safely. ## See Also - [Installation Guide](https://docs.aspose.org/slides/net/getting-started/installation/) - [Features Overview](https://docs.aspose.org/slides/net/developer-guide/features/) - [API Reference](https://reference.aspose.org/slides/net/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Slides for .NET — Enterprise Product](https://products.aspose.com/slides/net/) --- # Aspose.Slides FOSS for .NET — Key Features URL: https://blog.aspose.org/slides/net/dotnet-pptx-slides-shapes-api/ Explore the key features of Aspose.Slides FOSS for .NET: creating and saving PPTX presentations, managing slides, adding shapes with fill and text, and applying visual effects — free, MIT-licensed, no Office required. --- Product: Aspose.Slides Platform: net Page Type: index Canonical URL: https://blog.aspose.org/slides/net/dotnet-pptx-slides-shapes-api/ --- # Aspose.Slides FOSS for .NET — Key Features ## Introduction Aspose.Slides FOSS for .NET (`Aspose.Slides.Foss` on NuGet) is a free, MIT-licensed library for creating and editing PowerPoint `.pptx` files entirely in C#. It runs on Windows, macOS, Linux, and Docker containers with no dependency on Microsoft Office. This article walks through the key features available in the current release. --- ## Key Features ### Presentation Loading and Saving `Presentation` is the root object. Construct it with no arguments to create a new file or pass a file path to load an existing one. Call `Save()` with a path and `SaveFormat` to write the output. Use `using` to ensure resources are released: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Export; // Create new using var prs = new Presentation(); prs.Save("output.pptx", SaveFormat.Pptx); // Load and save using var prs2 = new Presentation("existing.pptx"); prs2.Save("copy.pptx", SaveFormat.Pptx); ``` ### Slide Management The `Slides` property returns the slide collection. Add slides with `AddEmptySlide()`, remove them with `Remove()`, and access existing slides by index: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Export; using var prs = new Presentation(); var slide = prs.Slides[0]; // First slide (created automatically) // Add a second slide using the first master/layout var layout = prs.Masters[0].LayoutSlides[0]; var newSlide = prs.Slides.AddEmptySlide(layout); prs.Save("two_slides.pptx", SaveFormat.Pptx); ``` ### AutoShape Insertion and Text Add shapes using `slide.Shapes.AddAutoShape()`. Capture the returned `ITextFrame` from `AddTextFrame()` to set text content and apply character formatting: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Export; using var prs = new Presentation(); var slide = prs.Slides[0]; var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 300, 100); var tf = shape.AddTextFrame("Hello from Aspose.Slides FOSS"); var fmt = tf.Paragraphs[0].Portions[0].PortionFormat; fmt.FontHeight = 24; fmt.FontBold = NullableBool.True; prs.Save("shape_demo.pptx", SaveFormat.Pptx); ``` ### Solid and Gradient Fills Apply `FillType.Solid` with an ARGB color or `FillType.Gradient` for multi-stop fills: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Drawing; using Aspose.Slides.Foss.Export; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 400, 200); shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.FromArgb(255, 70, 130, 180); prs.Save("solid_fill.pptx", SaveFormat.Pptx); ``` ### Visual Effects Apply outer shadows, glow, and soft-edge effects via `shape.EffectFormat`: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Drawing; using Aspose.Slides.Foss.Export; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 300, 150); var ef = shape.EffectFormat; ef.EnableOuterShadowEffect(); ef.OuterShadowEffect.BlurRadius = 8; ef.OuterShadowEffect.Distance = 6; ef.OuterShadowEffect.Direction = 45; ef.OuterShadowEffect.ShadowColor.Color = Color.FromArgb(128, 0, 0, 0); prs.Save("shadow.pptx", SaveFormat.Pptx); ``` --- ## Quick Start Install from NuGet (.NET 9.0 or later required): ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Export; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 400, 150); shape.AddTextFrame("My first slide"); prs.Save("first.pptx", SaveFormat.Pptx); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PowerPoint (OOXML) | `.pptx` | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Slides FOSS for .NET is released under the MIT License. Install from NuGet as `Aspose.Slides.Foss`. Commercial use, redistribution, and modification are all permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/slides/net/getting-started/) - [Developer Guide](https://docs.aspose.org/slides/net/developer-guide/) - [KB Articles](https://kb.aspose.org/slides/net/) - [API Reference](https://reference.aspose.org/slides/net/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Presentation Management with Aspose.Slides FOSS for .NET URL: https://blog.aspose.org/slides/net/slides-presentation-management-net/ Learn how to create, modify, and save PowerPoint PPTX presentations programmatically in C# using Aspose.Slides FOSS for .NET. Open source, MIT licensed. --- Product: Aspose.Slides Platform: net Page Type: index Canonical URL: https://blog.aspose.org/slides/net/slides-presentation-management-net/ --- # Presentation Management with Aspose.Slides FOSS for .NET ## Introduction Aspose.Slides FOSS for .NET provides a comprehensive set of classes for managing PowerPoint presentations entirely in C#. The library lets you create new `.pptx` files from scratch, load existing ones, manipulate slides and shapes, and save the result back to disk -- all without installing Microsoft Office or any external dependency. The `Aspose.Slides.Foss` NuGet package targets .NET 9.0 and runs identically on Windows, macOS, Linux, and Docker containers. It is released under the MIT license, so you can use it in commercial and open-source projects with no restrictions. This post walks through the core presentation management capabilities: working with slides, building shape hierarchies, organizing text, managing tables, and saving to PPTX. --- ## What's Included ### Creating and Loading Presentations The `Presentation` class is the entry point for every operation. You can create an empty presentation, load one from a file path, or read from a stream. The class implements `IDisposable`, so wrapping it in a `using` statement ensures resources are released properly. ```csharp // Create a brand-new, empty presentation using var pres = new Presentation(); // Load an existing file using var existing = new Presentation("report.pptx"); ``` The `Presentation` object exposes the full slide hierarchy through properties such as `Slides`, `Masters`, `LayoutSlides`, `Sections`, `CommentAuthors`, `Images`, and `NotesSize`. ### Working with Slides The `SlideCollection` returned by `Presentation.Slides` supports adding, cloning, inserting, reordering, and removing slides. You can clone a slide within the same presentation or across presentations while preserving or remapping layouts. ```csharp using var pres = new Presentation(); // The default presentation contains one blank slide var firstSlide = pres.Slides[0]; // Clone the first slide and append it pres.Slides.AddClone(firstSlide); // Insert a clone at a specific position pres.Slides.InsertClone(1, firstSlide); // Remove a slide by index pres.Slides.RemoveAt(2); // Total slide count int count = pres.Slides.Count; ``` Each `Slide` exposes `SlideNumber`, `Hidden`, `LayoutSlide`, `NotesSlideManager`, and `Name`. You can iterate the collection with `foreach` or convert it to an array with `ToArray()`. ### Shapes and AutoShapes Every slide contains a `ShapeCollection` accessible through `Slide.Shapes`. Use `AddAutoShape()`, `AddConnector()`, and `AddPictureFrame()` to add the most common shape types. ```csharp using var pres = new Presentation(); var slide = pres.Slides[0]; // Add a rectangle AutoShape var rect = slide.Shapes.AddAutoShape( ShapeType.Rectangle, 50, 50, 300, 150); // Add a connector var connector = slide.Shapes.AddConnector( ShapeType.BentConnector3, 100, 200, 200, 50); // Reorder a shape to bring it forward slide.Shapes.Reorder(0, rect); // Remove all shapes slide.Shapes.Clear(); ``` The `AddAutoShape` and `InsertAutoShape` methods accept a `ShapeType` enum value plus position and size coordinates. `AddConnector`, `InsertConnector`, `AddPictureFrame`, and `InsertPictureFrame` follow the same pattern. ### Text: Paragraphs and Portions Text in a presentation lives inside a `TextFrame`, which contains a `ParagraphCollection`. Each `Paragraph` holds a `PortionCollection` of `Portion` objects representing individual text runs with independent formatting. ```csharp using var pres = new Presentation(); var slide = pres.Slides[0]; var shape = slide.Shapes.AddAutoShape( ShapeType.Rectangle, 50, 50, 400, 200); // Access the shape's text frame var tf = shape.TextFrame; // Read or set the full text tf.Text = "Hello, presentation world!"; // Work with individual paragraphs and portions var para = new Paragraph(); var portion = new Portion("Formatted run"); para.Portions.Add(portion); tf.Paragraphs.Add(para); ``` Each `Portion` has a `PortionFormat` property for controlling font, size, bold/italic, color, underline, and other character-level attributes. `ParagraphFormat` controls alignment, bullet style, spacing, and indentation. ### Tables Tables are added through `ShapeCollection.AddTable`, which accepts column widths and row heights as arrays. The returned `Table` object provides access to `Rows`, `Columns`, and individual `Cell` objects. ```csharp using var pres = new Presentation(); var slide = pres.Slides[0]; double[] colWidths = { 150, 150, 150 }; double[] rowHeights = { 40, 40, 40 }; var table = slide.Shapes.AddTable( 50, 50, colWidths, rowHeights); // Merge cells in the second row table.MergeCells(table.Rows[1][0], table.Rows[1][2], false); // Apply a visual style preset table.StylePreset = TableStylePreset.MediumStyle2Accent1; ``` ### Saving Presentations The `Presentation.Save` method writes the document to a file or stream. The `SaveFormat` enum specifies the output format. PPTX is the primary supported output format. ```csharp using var pres = new Presentation(); // ... build slides ... // Save to a file pres.Save("output.pptx", SaveFormat.Pptx); // Save to a stream using var ms = new MemoryStream(); pres.Save(ms, SaveFormat.Pptx); // Save specific slides by index pres.Save("subset.pptx", new[] { 1, 3 }, SaveFormat.Pptx); ``` You can also pass a `SaveOptions` object for additional control over the output. --- ## Quick Start Install the Aspose.Slides FOSS package for .NET using the .NET CLI: Then create and save a minimal presentation: ```csharp using Aspose.Slides.Foss; using Aspose.Slides.Foss.Export; // 1. Create a new presentation using var pres = new Presentation(); // 2. Get the default slide var slide = pres.Slides[0]; // 3. Add a title shape var title = slide.Shapes.AddAutoShape( ShapeType.Rectangle, 50, 30, 600, 60); title.AddTextFrame("Quarterly Report"); // 4. Add a content shape var body = slide.Shapes.AddAutoShape( ShapeType.Rectangle, 50, 120, 600, 300); var bodyTf = body.AddTextFrame(""); var para = new Paragraph(); para.Portions.Add(new Portion("Revenue grew 12% year-over-year.")); bodyTf.Paragraphs.Add(para); // 5. Save as PPTX pres.Save("quarterly-report.pptx", SaveFormat.Pptx); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PPTX | .pptx | Yes | Yes | | PPSX | .ppsx | No | Planned | | PPTM | .pptm | No | Planned | | POTX | .potx | No | Planned | | ODP | .odp | No | Planned | | FODP | .fodp | No | Planned | > **Note:** PPTX read and write are fully implemented. Other `SaveFormat` enum values (PPSX, PPTM, ODP, etc.) are defined for forward compatibility and will be functional in future releases. --- ## Open Source & Licensing Aspose.Slides FOSS for .NET is released under the MIT license. The full source code is available on [GitHub](https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-.NET). You can use it in commercial and open-source projects, modify the code, and redistribute it without restriction. No API key, license file, or registration is required. --- ## Getting Started - **Developer Guide**: [docs.aspose.org/slides/net/](https://docs.aspose.org/slides/net/) -- tutorials and conceptual documentation. - **Knowledge Base**: [kb.aspose.org/slides/net/](https://kb.aspose.org/slides/net/) -- FAQs and how-to articles. - **API Reference**: [reference.aspose.org/slides/net/](https://reference.aspose.org/slides/net/) -- full class and method reference. ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Visual Effects in PowerPoint Presentations with .NET URL: https://blog.aspose.org/slides/net/slides-visual-effects-dotnet/ Use Aspose.Slides FOSS for .NET to apply solid and gradient fills, outer shadows, glow effects, and 3D bevels to PowerPoint shapes. No Office required. --- Product: Aspose.Slides Platform: net Page Type: index Canonical URL: https://blog.aspose.org/slides/net/slides-visual-effects-dotnet/ --- # Visual Effects in PowerPoint Presentations with .NET Aspose.Slides FOSS for .NET lets you apply professional-quality visual effects to PowerPoint shapes entirely in C#, with no Microsoft Office and no API keys. This post demonstrates the fill system, 2D effects, and 3D formatting available in the library. --- ## The Fill System Every shape has a `FillFormat` that controls how its interior is painted. The five fill types cover the full range of PowerPoint's design palette. ### Solid Fill The simplest fill, a flat color with optional transparency: ```csharp using Aspose.Slides.Foss; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape( ShapeType.RoundCornerRectangle, 100, 100, 400, 150 ); shape.AddTextFrame("Solid Fill"); shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.FromArgb(255, 30, 80, 180); prs.Save("solid.pptx", SaveFormat.Pptx); ``` ### Linear Gradient Fill Gradient stops let you blend from one color to another across the shape: ```csharp using Aspose.Slides.Foss; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape( ShapeType.Rectangle, 100, 100, 400, 150 ); var ff = shape.FillFormat; ff.FillType = FillType.Gradient; var gf = ff.GradientFormat; gf.GradientShape = GradientShape.Linear; gf.LinearGradientAngle = 90; // top-to-bottom gf.GradientStops.Add(0.0f, Color.FromArgb(255, 30, 80, 180)); // top: blue gf.GradientStops.Add(1.0f, Color.FromArgb(255, 0, 200, 160)); // bottom: teal prs.Save("gradient.pptx", SaveFormat.Pptx); ``` --- ## 2D Visual Effects ### Outer Drop Shadow Attach a semi-transparent drop shadow to any shape: ```csharp using Aspose.Slides.Foss; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape( ShapeType.RoundCornerRectangle, 100, 100, 350, 150 ); shape.AddTextFrame("Drop Shadow"); shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.White; var ef = shape.EffectFormat; ef.EnableOuterShadowEffect(); ef.OuterShadowEffect.BlurRadius = 12; ef.OuterShadowEffect.Direction = 315; // upper-left ef.OuterShadowEffect.Distance = 8; ef.OuterShadowEffect.ShadowColor.Color = Color.FromArgb(100, 0, 0, 0); prs.Save("shadow.pptx", SaveFormat.Pptx); ``` ### Glow Effect A colored halo around the shape edge: ```csharp using Aspose.Slides.Foss; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape( ShapeType.Ellipse, 150, 100, 250, 250 ); shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.FromArgb(255, 20, 60, 140); var ef = shape.EffectFormat; ef.EnableGlowEffect(); ef.GlowEffect.Radius = 20; ef.GlowEffect.Color.Color = Color.FromArgb(200, 0, 180, 255); prs.Save("glow.pptx", SaveFormat.Pptx); ``` --- ## 3D Formatting ### Bevel and Material The `ThreeDFormat` property gives any flat shape a three-dimensional appearance. Combine a bevel with a camera preset and a material for the richest result: ```csharp using Aspose.Slides.Foss; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape( ShapeType.Rectangle, 150, 150, 300, 130 ); shape.AddTextFrame("Metal Button"); // Blue solid fill shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.FromArgb(255, 20, 70, 160); // 3D bevel + camera + light + material var tdf = shape.ThreeDFormat; tdf.BevelTop.BevelType = BevelPresetType.Circle; tdf.BevelTop.Width = 10; tdf.BevelTop.Height = 5; tdf.Camera.CameraType = CameraPresetType.PerspectiveAbove; tdf.LightRig.LightType = LightRigPresetType.Balanced; tdf.LightRig.Direction = LightingDirection.Top; tdf.Material = MaterialPresetType.Metal; tdf.Depth = 20; prs.Save("metal-button.pptx", SaveFormat.Pptx); ``` --- ## Combining Effects on the Same Shape Shadow and 3D formatting can coexist on a single shape, enabling polished "card" designs: ```csharp using Aspose.Slides.Foss; using var prs = new Presentation(); var shape = prs.Slides[0].Shapes.AddAutoShape( ShapeType.RoundCornerRectangle, 120, 120, 360, 150 ); shape.AddTextFrame("Premium Card"); // Fill shape.FillFormat.FillType = FillType.Solid; shape.FillFormat.SolidFillColor.Color = Color.FromArgb(255, 30, 80, 180); // 3D bevel var tdf = shape.ThreeDFormat; tdf.BevelTop.BevelType = BevelPresetType.Circle; tdf.BevelTop.Width = 8; tdf.Camera.CameraType = CameraPresetType.PerspectiveAbove; tdf.Material = MaterialPresetType.Plastic; // Drop shadow var ef = shape.EffectFormat; ef.EnableOuterShadowEffect(); ef.OuterShadowEffect.BlurRadius = 14; ef.OuterShadowEffect.Direction = 270; ef.OuterShadowEffect.Distance = 8; ef.OuterShadowEffect.ShadowColor.Color = Color.FromArgb(70, 0, 0, 0); prs.Save("premium-card.pptx", SaveFormat.Pptx); ``` --- ## Installation No Office installation, no license keys, no network calls; all processing happens locally. --- ## Getting Started - [Getting Started](https://docs.aspose.org/slides/net/getting-started/) - [Developer Guide](https://docs.aspose.org/slides/net/developer-guide/) - [KB Articles](https://kb.aspose.org/slides/net/) - [API Reference](https://reference.aspose.org/slides/net/) ## Related Resources - [EffectFormat and ThreeDFormat reference](https://reference.aspose.org/slides/net/EffectFormat/) - [FillFormat reference](https://reference.aspose.org/slides/net/FillFormat/) - [Getting Started](https://docs.aspose.org/slides/net/getting-started/) - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Slides FOSS for Python URL: https://blog.aspose.org/slides/python/ --- Product: Aspose.Slides Platform: python Page Type: index Canonical URL: https://blog.aspose.org/slides/python/ --- # Aspose.Slides FOSS for Python ## Related Topics - [Charts In Python -- Aspose.Slides FOSS for Python](https://blog.aspose.org/slides/python/python-powerpoint-chart-create/) - [Introducing Aspose.Slides FOSS for Python](https://blog.aspose.org/slides/python/python-powerpoint-pptx-library/) - [Aspose.Slides FOSS for Python — Key Features](https://blog.aspose.org/slides/python/python-pptx-slides-shapes-api/) - [Presentation Management in Python with Aspose.Slides FOSS](https://blog.aspose.org/slides/python/slides-presentation-management-python/) - [Visual Effects in PowerPoint Presentations with Python](https://blog.aspose.org/slides/python/slides-visual-effects-python/) --- # Charts In Python -- Aspose.Slides FOSS for Python URL: https://blog.aspose.org/slides/python/python-powerpoint-chart-create/ Deep dive into charts in python with Aspose.Slides FOSS for Python. --- Product: Aspose.Slides Platform: python Page Type: index Canonical URL: https://blog.aspose.org/slides/python/python-powerpoint-chart-create/ --- # Charts In Python -- Aspose.Slides FOSS for Python Aspose.Slides FOSS for Python provides powerful capabilities for working with charts in python. ## Overview The key classes for this feature area include: - **`Chart`** - **`ChartSeries`** - **`ChartSeriesCollection`** - **`ChartSeriesGroup`** - **`ChartSeriesGroupCollection`** ## Getting Started Install the package: ## Key Capabilities Aspose.Slides FOSS for Python lets you work with charts in python programmatically without external dependencies. ## Learn More - [Developer Guide](https://docs.aspose.org/slides/python/developer-guide/) - [API Reference](https://reference.aspose.org/slides/python/) - [Knowledge Base](https://kb.aspose.org/slides/python/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Slides for Python — Enterprise Product](https://products.aspose.com/slides/python-net/) --- # Introducing Aspose.Slides FOSS for Python URL: https://blog.aspose.org/slides/python/python-powerpoint-pptx-library/ Aspose.Slides FOSS for Python is a free, open-source library for creating and editing PowerPoint presentations without Microsoft Office. MIT licensed, pure Python, no API key required. --- Product: Aspose.Slides Platform: python Page Type: index Canonical URL: https://blog.aspose.org/slides/python/python-powerpoint-pptx-library/ --- # Introducing Aspose.Slides FOSS for Python ## Introduction Aspose.Slides FOSS for Python is now available on PyPI: a free, MIT-licensed library for creating, reading, and editing PowerPoint `.pptx` files entirely in Python, with no dependency on Microsoft Office or any proprietary runtime. The library is designed for developers who need to generate or manipulate presentation files programmatically: automating slide decks from data, extracting text and metadata from uploaded PPTX files, building presentation-based reporting pipelines, or embedding presentation creation into web applications. Because `aspose-slides-foss` is pure Python with only `lxml` as a dependency, it deploys identically on Windows, macOS, Linux, and Docker containers. ## Key Features - **Full round-trip PPTX support**: Open any `.pptx` file, modify its content, and save it back without losing unknown XML parts that the library does not yet understand. - **Slides management**: Add, remove, and iterate slides using `prs.slides`; the presentation starts with one blank slide after `slides.Presentation()`. - **AutoShapes, Tables, and Connectors**: Insert shapes via `slide.shapes.add_auto_shape()`, tabular data via `slide.shapes.add_table()`, and visual connectors between shapes via `slide.shapes.add_connector()`. - **Rich text formatting**: Format text at character level with `PortionFormat`: font size, bold, italic, underline, and ARGB color via `FillType.SOLID` and `Color.from_argb()`. - **Fill types**: Apply `FillType.SOLID`, `GRADIENT`, `PATTERN`, or `PICTURE` fills to any shape. - **Visual effects**: Outer shadow, glow, soft edge, blur, reflection, and inner shadow via `shape.effect_format`. - **3D formatting**: Bevel, camera, light rig, material, and extrusion depth via `shape.three_d_format`. - **Speaker notes**: Attach notes text to each slide via `notes_slide_manager.add_notes_slide()`. - **Threaded comments**: Add comments with author metadata and slide position. - **Embedded images**: Embed from file path, bytes, or `io.BytesIO` stream. - **Document properties**: Read and write core, app, and custom properties. ## Getting Started Install from PyPI. Python 3.10 or later is required; `lxml` is installed automatically. Create your first presentation with a shape and save it: ```python import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat from aspose.slides_foss import ShapeType with slides.Presentation() as prs: slide = prs.slides[0] shape = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 50, 400, 120) shape.add_text_frame("Hello from Aspose.Slides FOSS!") prs.save("hello.pptx", SaveFormat.PPTX) ``` Always use `Presentation` inside a `with` block; this ensures all internal resources are released when the block exits. ## Text Formatting Example ```python import aspose.slides_foss as slides from aspose.slides_foss import ShapeType, NullableBool, FillType from aspose.slides_foss.drawing import Color from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 50, 500, 150) tf = shape.add_text_frame("Bold heading in corporate blue") fmt = tf.paragraphs[0].portions[0].portion_format fmt.font_height = 28 fmt.font_bold = NullableBool.TRUE fmt.fill_format.fill_type = FillType.SOLID fmt.fill_format.solid_fill_color.color = Color.from_argb(255, 0, 70, 127) prs.save("formatted.pptx", SaveFormat.PPTX) ``` ## Current Limitations The following areas raise `NotImplementedError` in this release: - Charts, SmartArt, and OLE objects - Animations and slide transitions - Export to PDF, HTML, SVG, or image formats - Hyperlinks, action settings, VBA macros, and digital signatures Unknown XML parts encountered during load are preserved verbatim on save, so PPTX files produced by other tools round-trip safely. ## See Also - [Installation Guide](https://docs.aspose.org/slides/python/getting-started/installation/) - [Features Overview](https://docs.aspose.org/slides/python/developer-guide/features/) - [How to Create Presentations](https://kb.aspose.org/slides/python/how-to-create-presentations-python/) - [How to Add Shapes](https://kb.aspose.org/slides/python/how-to-add-shapes-python/) - [API Reference](https://reference.aspose.org/slides/python/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Slides FOSS for Python — Key Features URL: https://blog.aspose.org/slides/python/python-pptx-slides-shapes-api/ Explore the key features of Aspose.Slides FOSS for Python: creating and saving PPTX presentations, managing slides, adding shapes with fill and text, and applying visual effects — free, MIT-licensed, no Office required. --- Product: Aspose.Slides Platform: python Page Type: index Canonical URL: https://blog.aspose.org/slides/python/python-pptx-slides-shapes-api/ --- # Aspose.Slides FOSS for Python — Key Features ## Introduction Aspose.Slides FOSS for Python (`aspose-slides-foss` on PyPI) is a free, MIT-licensed library for creating and editing PowerPoint `.pptx` files entirely in Python. It runs on Windows, macOS, Linux, and Docker containers with no dependency on Microsoft Office. This article walks through the key features available in version 26.3.2. --- ## Key Features ### Presentation Loading and Saving `Presentation` is the root object. Construct it with no arguments to create a new file or pass a file path to load an existing one. Call `save()` with a `SaveFormat` to write the output: ```python from aspose.slides_foss import Presentation from aspose.slides_foss.export import SaveFormat # Create new prs = Presentation() prs.save("output.pptx", SaveFormat.PPTX) # Load and save prs2 = Presentation("existing.pptx") prs2.save("copy.pptx", SaveFormat.PPTX) ``` ### Slide Management The `slides` property returns a `SlideCollection`. Add slides with `add_empty_slide()`, remove them with `remove()`, and access existing slides by index: ```python from aspose.slides_foss import Presentation from aspose.slides_foss.export import SaveFormat prs = Presentation() slide = prs.slides[0] # First slide (created automatically) # Add a second slide using the first master/layout layout = prs.masters[0].layout_slides[0] new_slide = prs.slides.add_empty_slide(layout) prs.save("two_slides.pptx", SaveFormat.PPTX) ``` ### AutoShape Insertion and Text Add shapes using `slide.shapes.add_auto_shape()`. Capture the returned `ITextFrame` from `add_text_frame()` to set text content: ```python from aspose.slides_foss import Presentation, ShapeType from aspose.slides_foss.export import SaveFormat prs = Presentation() slide = prs.slides[0] shape = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 50, 300, 100) tf = shape.add_text_frame("Hello from Aspose.Slides FOSS") tf.paragraphs[0].portions[0].portion_format.font_height = 24 prs.save("shape_demo.pptx", SaveFormat.PPTX) ``` ### Solid and Gradient Fills Apply `FillType.SOLID` with an ARGB color or `FillType.GRADIENT` for multi-stop fills: ```python from aspose.slides_foss import Presentation, ShapeType, FillType from aspose.slides_foss.drawing import Color from aspose.slides_foss.export import SaveFormat prs = Presentation() slide = prs.slides[0] shape = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 100, 100, 400, 200) shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 70, 130, 180) prs.save("solid_fill.pptx", SaveFormat.PPTX) ``` ### Visual Effects Apply outer shadows, glow, and soft-edge effects via `shape.effect_format`: ```python from aspose.slides_foss import ( Presentation, ShapeType, FillType, NullableBool ) from aspose.slides_foss.drawing import Color from aspose.slides_foss.export import SaveFormat prs = Presentation() slide = prs.slides[0] shape = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 100, 100, 300, 150) ef = shape.effect_format ef.enable_outer_shadow_effect() ef.outer_shadow_effect.blur_radius = 8 ef.outer_shadow_effect.distance = 6 ef.outer_shadow_effect.direction = 45 ef.outer_shadow_effect.shadow_color.color = Color.from_argb(128, 0, 0, 0) prs.save("shadow.pptx", SaveFormat.PPTX) ``` --- ## Quick Start ```python from aspose.slides_foss import Presentation, ShapeType from aspose.slides_foss.export import SaveFormat prs = Presentation() slide = prs.slides[0] shape = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 50, 400, 150) shape.add_text_frame("My first slide") prs.save("first.pptx", SaveFormat.PPTX) ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PowerPoint (OOXML) | `.pptx` | ✓ | ✓ | --- ## Open Source & Licensing Aspose.Slides FOSS for Python is released under the MIT License. Install from PyPI as `aspose-slides-foss`. Commercial use, redistribution, and modification are all permitted. --- ## Getting Started - [Getting Started](https://docs.aspose.org/slides/python/getting-started/) - [Developer Guide](https://docs.aspose.org/slides/python/developer-guide/) - [KB Articles](https://kb.aspose.org/slides/python/) - [API Reference](https://reference.aspose.org/slides/python/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Presentation Management in Python with Aspose.Slides FOSS URL: https://blog.aspose.org/slides/python/slides-presentation-management-python/ Manage PowerPoint presentations programmatically with Aspose.Slides FOSS for Python: create, clone, reorder, and save slides in PPTX format using a pure-Python, MIT-licensed library. --- Product: Aspose.Slides Platform: python Page Type: index Canonical URL: https://blog.aspose.org/slides/python/slides-presentation-management-python/ --- # Presentation Management in Python with Aspose.Slides FOSS ## Introduction This guide shows how to create, modify, and save PowerPoint presentations programmatically in Python using Aspose.Slides FOSS. The library lets you build slides from scratch, add and reorder slides, populate them with shapes, tables, and formatted text, and save the result to PPTX. All processing happens in pure Python with no dependency on Microsoft Office or any external binary. The library is available on PyPI as `aspose-slides-foss` under the MIT license. Install it with `pip`, import it, and start building presentations in a few lines of code. Whether you are automating report generation, building a slide-deck pipeline, or embedding presentation output in a web application, the API covers the full surface: slide collections, master/layout slides, shape collections, text frames, fill formats, and export options. This post walks through the core presentation-management capabilities — the classes and methods you will use most when working with slides in Python. --- ## What's Included ### Presentation Lifecycle The `Presentation` class is the entry point. Create a new deck, manipulate its contents, and save to PPTX. Use `Presentation` as a context manager with `with` to release file handles automatically. ```python import io from aspose.slides_foss import Presentation from aspose.slides_foss.export import SaveFormat with Presentation() as pres: # A new presentation starts with one blank slide print("Slides:", len(pres.slides)) # 1 # Save to a file pres.save("output.pptx", SaveFormat.PPTX) # Or save to a stream buf = io.BytesIO() pres.save(buf, SaveFormat.PPTX) ``` ### Slide Collection Operations `SlideCollection` lets you add, insert, clone, remove, and reorder slides. `len(pres.slides)` reflects the current count after each change. ```python from aspose.slides_foss import Presentation, ShapeType with Presentation() as pres: layout = pres.layout_slides[0] # Add a blank slide using the first layout pres.slides.add_empty_slide(layout) # Insert at a specific position pres.slides.insert_empty_slide(1, layout) # Clone an existing slide (shapes are copied) pres.slides[0].shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 50, 200, 100) pres.slides.add_clone(pres.slides[0]) print("Total slides:", len(pres.slides)) # 4 # Remove by index pres.slides.remove_at(3) ``` ### Shapes and AutoShapes Add rectangles, ellipses, triangles, and other geometry shapes to any slide via `ShapeCollection.add_auto_shape()`. Each shape exposes position, size, rotation, and fill properties that persist across save/reload cycles. ```python from aspose.slides_foss import Presentation, ShapeType with Presentation() as pres: slide = pres.slides[0] slide.shapes.clear() rect = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 50, 300, 150) rect.rotation = 15 ellipse = slide.shapes.add_auto_shape(ShapeType.ELLIPSE, 400, 50, 200, 200) # Reorder z-index slide.shapes.reorder(0, ellipse) print("Front shape:", slide.shapes[0].shape_type) # ELLIPSE ``` ### Tables Create data tables with `ShapeCollection.add_table()`, set cell text via `TextFrame`, merge cells, and apply border formatting. Row heights and column widths match the values you pass to the constructor. ```python from aspose.slides_foss import Presentation, FillType from aspose.slides_foss.drawing import Color with Presentation() as pres: slide = pres.slides[0] slide.shapes.clear() table = slide.shapes.add_table(50, 50, [150, 150, 150], [40, 40, 40]) # Merge two cells in the second row table.merge_cells(table.rows[1][0], table.rows[1][1], False) # Style the header row with a bottom border for col_idx in range(len(table.columns)): fmt = table.rows[0][col_idx].cell_format fmt.border_bottom.fill_format.fill_type = FillType.SOLID fmt.border_bottom.fill_format.solid_fill_color.color = Color.from_argb(255, 0, 0, 0) fmt.border_bottom.width = 2 ``` ### Master and Layout Slides Every presentation has a hierarchy of master slides and layout slides. Access them through `Presentation.masters` and `Presentation.layout_slides` to apply consistent formatting across your deck. ```python from aspose.slides_foss import Presentation with Presentation() as pres: master = pres.masters[0] print("Master layouts:", len(master.layout_slides)) # Pick a layout by type from aspose.slides_foss import SlideLayoutType title_layout = pres.layout_slides.get_by_type(SlideLayoutType.TITLE) if title_layout: pres.slides.add_empty_slide(title_layout) ``` ### Document Properties Read and write built-in metadata such as title, author, and subject through the `DocumentProperties` object. Set any of these properties before calling `save()` — they are embedded in the PPTX metadata and readable by downstream tools: ```python from aspose.slides_foss import Presentation from aspose.slides_foss.export import SaveFormat with Presentation() as pres: props = pres.document_properties props.title = "Quarterly Report" props.author = "Engineering" props.subject = "Q1 2026 Results" pres.save("report.pptx", SaveFormat.PPTX) ``` --- ## Quick Start Run the following pip command to install Aspose.Slides FOSS for Python from PyPI: The following example creates a presentation with a title shape, a data table, and a fill, then saves it to PPTX: ```python from aspose.slides_foss import Presentation, ShapeType, FillType, NullableBool from aspose.slides_foss.drawing import Color from aspose.slides_foss.export import SaveFormat with Presentation() as pres: slide = pres.slides[0] slide.shapes.clear() # Add a title shape title = slide.shapes.add_auto_shape(ShapeType.RECTANGLE, 50, 30, 860, 80) tf = title.add_text_frame("Quarterly Report") tf.paragraphs[0].portions[0].portion_format.font_bold = NullableBool.TRUE tf.paragraphs[0].portions[0].portion_format.font_height = 28 # Add a data table table = slide.shapes.add_table(50, 150, [200, 200, 200], [40, 40, 40]) headers = ["Region", "Revenue", "Growth"] for i, h in enumerate(headers): table.rows[0][i].text_frame.text = h # Fill the title shape background title.fill_format.fill_type = FillType.SOLID title.fill_format.solid_fill_color.color = Color.from_argb(255, 0, 51, 102) # Save as PPTX pres.save("report.pptx", SaveFormat.PPTX) ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | PPTX | .pptx | ✓ | ✓ | | PPT | .ppt | — | Planned | | PPSX | .ppsx | — | Planned | | PPTM | .pptm | — | Planned | | POTX | .potx | — | Planned | | ODP | .odp | — | Planned | | PDF | .pdf | — | Planned | | HTML | .html | — | Planned | | HTML5 | .html | — | Planned | | TIFF | .tiff | — | Planned | | GIF | .gif | — | Planned | | XPS | .xps | — | Planned | | FODP | .fodp | — | Planned | | MD | .md | — | Planned | **Note:** PPTX read and write are fully implemented. Other `SaveFormat` values (PPT, ODP, PDF, etc.) are planned for future releases; passing them to `save()` currently produces PPTX output. --- ## Open Source & Licensing Aspose.Slides FOSS for Python is released under the MIT license. You can use it in personal, academic, and commercial projects without restrictions. The source code is available on [GitHub](https://github.com/aspose-slides-foss/Aspose.Slides-FOSS-for-Python) and the package is published on [PyPI](https://pypi.org/project/aspose-slides-foss/). --- ## Getting Started - [Getting Started](https://docs.aspose.org/slides/python/getting-started/) - [Developer Guide](https://docs.aspose.org/slides/python/developer-guide/) - [KB Articles](https://kb.aspose.org/slides/python/) - [API Reference](https://reference.aspose.org/slides/python/) ## Related Resources - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Visual Effects in PowerPoint Presentations with Python URL: https://blog.aspose.org/slides/python/slides-visual-effects-python/ Use Aspose.Slides FOSS for Python to apply solid and gradient fills, outer shadows, glow effects, and 3D bevels to PowerPoint shapes. No Office required. --- Product: Aspose.Slides Platform: python Page Type: index Canonical URL: https://blog.aspose.org/slides/python/slides-visual-effects-python/ --- # Visual Effects in PowerPoint Presentations with Python ## Introduction Aspose.Slides FOSS for Python lets you apply professional-quality visual effects to PowerPoint shapes entirely in Python, with no Microsoft Office and no API keys required. This guide shows how to use the fill system (solid and gradient), 2D effects (drop shadows and glow), and 3D formatting (bevels, camera presets, and materials) to produce polished presentations from code. ## Quick Start Install the package and apply a solid fill to a shape in a few lines: ```python import aspose.slides_foss as slides from aspose.slides_foss import ShapeType, FillType from aspose.slides_foss.drawing import Color from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.ROUND_CORNER_RECTANGLE, 100, 100, 400, 150 ) shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 30, 80, 180) prs.save("out.pptx", SaveFormat.PPTX) ``` --- ## The Fill System Every shape has a `fill_format` that controls how its interior is painted. The five fill types cover the full range of PowerPoint's design palette. ### Solid Fill `FillType.SOLID` paints the shape interior with a flat color. Set `solid_fill_color.color` with a `Color.from_argb()` value to control hue and optional transparency: ```python from aspose.slides_foss import ShapeType, FillType from aspose.slides_foss.drawing import Color import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.ROUND_CORNER_RECTANGLE, 100, 100, 400, 150 ) shape.add_text_frame("Solid Fill") shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 30, 80, 180) prs.save("solid.pptx", SaveFormat.PPTX) ``` ### Linear Gradient Fill `FillType.GRADIENT` transitions between two or more colors across the shape. Add stops with `gradient_stops.add()`, set `gradient_shape = GradientShape.LINEAR`, and control the direction with `linear_gradient_angle` (90 = top-to-bottom): ```python from aspose.slides_foss import ShapeType, FillType, GradientShape from aspose.slides_foss.drawing import Color import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.RECTANGLE, 100, 100, 400, 150 ) ff = shape.fill_format ff.fill_type = FillType.GRADIENT gf = ff.gradient_format gf.gradient_shape = GradientShape.LINEAR gf.linear_gradient_angle = 90 # top-to-bottom gf.gradient_stops.add(0.0, Color.from_argb(255, 30, 80, 180)) # top: blue gf.gradient_stops.add(1.0, Color.from_argb(255, 0, 200, 160)) # bottom: teal prs.save("gradient.pptx", SaveFormat.PPTX) ``` --- ## 2D Visual Effects ### Outer Drop Shadow Call `effect_format.enable_outer_shadow_effect()` to attach a drop shadow. Configure `blur_radius` (softness), `direction` (angle in degrees), and `distance` (offset from the shape edge): ```python from aspose.slides_foss import ShapeType, FillType from aspose.slides_foss.drawing import Color import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.ROUND_CORNER_RECTANGLE, 100, 100, 350, 150 ) shape.add_text_frame("Drop Shadow") shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 255, 255, 255) ef = shape.effect_format ef.enable_outer_shadow_effect() ef.outer_shadow_effect.blur_radius = 12 ef.outer_shadow_effect.direction = 315 # upper-left ef.outer_shadow_effect.distance = 8 ef.outer_shadow_effect.shadow_color.color = Color.from_argb(100, 0, 0, 0) prs.save("shadow.pptx", SaveFormat.PPTX) ``` ### Glow Effect Call `effect_format.enable_glow_effect()` to surround a shape with a colored halo. Set `radius` to control how far the glow extends from the edge (in points), then configure the glow color independently from the shape fill: ```python from aspose.slides_foss import ShapeType, FillType from aspose.slides_foss.drawing import Color import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.ELLIPSE, 150, 100, 250, 250 ) shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 20, 60, 140) ef = shape.effect_format ef.enable_glow_effect() ef.glow_effect.radius = 20 ef.glow_effect.color.color = Color.from_argb(200, 0, 180, 255) prs.save("glow.pptx", SaveFormat.PPTX) ``` --- ## 3D Formatting ### Bevel and Material The `three_d_format` property gives any flat shape a three-dimensional appearance. Combine a bevel with a camera preset and a material for the richest result: ```python from aspose.slides_foss import ( ShapeType, FillType, BevelPresetType, CameraPresetType, LightRigPresetType, LightingDirection, MaterialPresetType, ) from aspose.slides_foss.drawing import Color import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.RECTANGLE, 150, 150, 300, 130 ) shape.add_text_frame("Metal Button") # Blue solid fill shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 20, 70, 160) # 3D bevel + camera + light + material tdf = shape.three_d_format tdf.bevel_top.bevel_type = BevelPresetType.CIRCLE tdf.bevel_top.width = 10 tdf.bevel_top.height = 5 tdf.camera.camera_type = CameraPresetType.PERSPECTIVE_ABOVE tdf.light_rig.light_type = LightRigPresetType.BALANCED tdf.light_rig.direction = LightingDirection.TOP tdf.material = MaterialPresetType.METAL tdf.depth = 20 prs.save("metal-button.pptx", SaveFormat.PPTX) ``` --- ## Combining Effects on the Same Shape Shadow and 3D formatting can coexist on a single shape, enabling polished "card" designs: ```python from aspose.slides_foss import ( ShapeType, FillType, BevelPresetType, CameraPresetType, MaterialPresetType, ) from aspose.slides_foss.drawing import Color import aspose.slides_foss as slides from aspose.slides_foss.export import SaveFormat with slides.Presentation() as prs: shape = prs.slides[0].shapes.add_auto_shape( ShapeType.ROUND_CORNER_RECTANGLE, 120, 120, 360, 150 ) shape.add_text_frame("Premium Card") # Fill shape.fill_format.fill_type = FillType.SOLID shape.fill_format.solid_fill_color.color = Color.from_argb(255, 30, 80, 180) # 3D bevel tdf = shape.three_d_format tdf.bevel_top.bevel_type = BevelPresetType.CIRCLE tdf.bevel_top.width = 8 tdf.camera.camera_type = CameraPresetType.PERSPECTIVE_ABOVE tdf.material = MaterialPresetType.PLASTIC # Drop shadow ef = shape.effect_format ef.enable_outer_shadow_effect() ef.outer_shadow_effect.blur_radius = 14 ef.outer_shadow_effect.direction = 270 ef.outer_shadow_effect.distance = 8 ef.outer_shadow_effect.shadow_color.color = Color.from_argb(70, 0, 0, 0) prs.save("premium-card.pptx", SaveFormat.PPTX) ``` --- ## Getting Started Install Aspose.Slides FOSS for Python from PyPI using pip (no compiler or runtime required): No Microsoft Office installation or license keys are required; all processing runs in the local Python process with no external dependencies. --- ## Related Resources - [EffectFormat and ThreeDFormat reference](https://reference.aspose.org/slides/python/EffectFormat/) - [FillFormat reference](https://reference.aspose.org/slides/python/FillFormat/) - [How to Apply 3D Effects](https://kb.aspose.org/slides/python/how-to-apply-3d-effects-python/) - [Working with 3D Effects: Developer Guide](https://docs.aspose.org/slides/python/developer-guide/working-with-3d-effects/) - [Getting Started](https://docs.aspose.org/slides/python/getting-started/) - [Aspose.Slides — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.TeX FOSS for Python URL: https://blog.aspose.org/tex/python/ --- Product: Aspose.TeX Platform: python Page Type: index Canonical URL: https://blog.aspose.org/tex/python/ --- # Aspose.TeX FOSS for Python Articles and tutorials for Aspose.TeX FOSS for Python. ## Related Topics - [Introducing Aspose.TeX FOSS for Python](https://blog.aspose.org/tex/python/introducing-tex-foss-python/) - [The Aspose.TeX Engine for Python — TeXJob, Devices, and Input Sources](https://blog.aspose.org/tex/python/tex-engine-python/) --- # Introducing Aspose.TeX FOSS for Python URL: https://blog.aspose.org/tex/python/introducing-tex-foss-python/ Aspose.TeX FOSS for Python is a free, MIT-licensed TeX typesetting engine. It processes TeX markup from strings or files and produces PDF, DVI, or SVG output without requiring a LaTeX installation or external runtime. --- Product: Aspose.TeX Platform: python Page Type: index Canonical URL: https://blog.aspose.org/tex/python/introducing-tex-foss-python/ --- # Introducing Aspose.TeX FOSS for Python ## Introduction Aspose.TeX FOSS for Python is a free, MIT-licensed TeX typesetting engine that runs entirely in Python -- no LaTeX installation, no Perl runtime, no external TeX distribution required. Install it with a single package manager command and call `TeXJob.run()` to convert TeX markup into PDF, DVI, or SVG output. The library is designed for document pipelines, math rendering, and academic publishing applications where TeX markup needs to be processed programmatically. It accepts input from file paths (`FileInputSource`) or in-memory strings (`StringInputSource`), making it suitable for both batch workflows and dynamic content generation. Aspose.TeX FOSS is released under the MIT license. Commercial use is permitted without restriction. --- ## Key Features ### PDF Output via PdfDevice The `PdfDevice` output device writes typeset content to a PDF byte stream. Construct a `TeXJob` with a `PdfDevice` and call `run()` to receive PDF bytes: ```python from aspose_tex import TeXJob, TeXOptions from aspose_tex import PdfDevice from aspose_tex import StringInputSource source = StringInputSource("Hello world!") job = TeXJob(source, PdfDevice(), options=TeXOptions()) pdf_bytes = job.run() ``` ### SVG Output via SvgDevice `SvgDevice` renders each typeset page as an SVG graphic. The `get_all_pages()` method returns a list of SVG byte strings, one per page: ```python from aspose_tex import TeXJob, TeXOptions from aspose_tex import SvgDevice from aspose_tex import StringInputSource device = SvgDevice() job = TeXJob(StringInputSource("Hello world!"), device, options=TeXOptions()) job.run() pages = device.get_all_pages() ``` ### DVI Output via DviDevice `DviDevice` produces Device Independent (DVI) output bytes -- the intermediate format used by traditional TeX workflows before final rendering: ```python from aspose_tex import TeXJob, TeXOptions from aspose_tex import DviDevice from aspose_tex import StringInputSource source = StringInputSource("Hello world!") job = TeXJob(source, DviDevice(), options=TeXOptions()) dvi_bytes = job.run() ``` ### File-Based Input with FileInputSource `FileInputSource` reads TeX markup from a file on disk: ```python from aspose_tex import TeXJob, TeXOptions from aspose_tex import PdfDevice from aspose_tex import FileInputSource job = TeXJob(FileInputSource("document.tex"), PdfDevice(), options=TeXOptions()) pdf_bytes = job.run() ``` ### In-Memory Input with StringInputSource `StringInputSource` accepts raw TeX markup as a Python string: ```python from aspose_tex import TeXJob, TeXOptions from aspose_tex import PdfDevice from aspose_tex import StringInputSource job = TeXJob(StringInputSource("Hello, world!"), PdfDevice(), options=TeXOptions()) pdf_bytes = job.run() ``` --- ## Quick Start Install the package: Typeset a TeX string to PDF: ```python from aspose_tex import TeXJob, TeXOptions from aspose_tex import PdfDevice from aspose_tex import StringInputSource pdf_bytes = TeXJob(StringInputSource("Hello!"), PdfDevice(), options=TeXOptions()).run() with open("output.pdf", "wb") as f: f.write(pdf_bytes) ``` --- ## Supported Formats | Format | Extension | Output Device | |-------|-----------|----------------| | PDF | .pdf | `PdfDevice` | | DVI | .dvi | `DviDevice` | | SVG | .svg | `SvgDevice` | Input is TeX markup supplied as a file path or in-memory string. This project is pre-alpha (see the [Developer Guide](https://docs.aspose.org/tex/python/developer-guide/) for current status); output format support is under active development. --- ## Open Source and Licensing Aspose.TeX FOSS for Python is released under the MIT license. Commercial use is permitted without fees or restrictions. --- ## Getting Started - [Installation Guide](https://docs.aspose.org/tex/python/getting-started/installation/) - [Developer Guide](https://docs.aspose.org/tex/python/developer-guide/) - [KB Articles](https://kb.aspose.org/tex/python/) - [API Reference](https://reference.aspose.org/tex/python/) ## Related Resources - [Aspose.TeX FOSS for Python — Open-Source TeX Engine](https://products.aspose.org/tex/python/) - [Aspose.TeX — Enterprise Blog](https://blog.aspose.com/) - [Aspose.TeX for Python — Enterprise Product](https://products.aspose.com/tex/python-net/) --- # The Aspose.TeX Engine for Python — TeXJob, Devices, and Input Sources URL: https://blog.aspose.org/tex/python/tex-engine-python/ Deep dive into the Aspose.TeX FOSS engine for Python: TeXJob entry point, PdfDevice, DviDevice, SvgDevice output devices, and FileInputSource and StringInputSource input handling. --- Product: Aspose.TeX Platform: python Page Type: index Canonical URL: https://blog.aspose.org/tex/python/tex-engine-python/ --- # The Aspose.TeX Engine for Python — TeXJob, Devices, and Input Sources ## Introduction Aspose.TeX FOSS for Python exposes a concise engine API built around three concepts: a unified entry point (`TeXJob`), pluggable output devices (`PdfDevice`, `DviDevice`, `SvgDevice`), and two input source types (`FileInputSource`, `StringInputSource`). This article covers each component and shows how they combine to produce PDF, DVI, and SVG output from TeX markup. --- ## TeXJob — The Entry Point `TeXJob` is the main class for driving the TeX engine. It accepts an input source, an output device, and optional `TeXOptions`, then runs the typesetting pipeline when `run()` is called. The return value is the output bytes for device types that produce a single output (PDF, DVI); for SVG output, pages are retrieved from the device object after `run()` completes. `TeXOptions` configures engine behavior. Constructing it with defaults (`TeXOptions()`) uses the standard TeX settings suitable for most documents. --- ## Output Devices ### PdfDevice `PdfDevice` writes the typeset document to a PDF byte stream. It is the standard output device for producing portable, printable output: ```python from aspose_tex import TeXJob, TeXOptions, PdfDevice, StringInputSource pdf_bytes = TeXJob(StringInputSource("Hello, world!"), PdfDevice(), options=TeXOptions()).run() with open("output.pdf", "wb") as f: f.write(pdf_bytes) ``` After `run()`, the returned bytes contain the complete PDF document. ### DviDevice `DviDevice` produces Device Independent (DVI) format output — the native intermediate format of TeX. DVI output can be consumed by downstream tools for rendering or further processing: ```python from aspose_tex import TeXJob, TeXOptions, DviDevice, StringInputSource dvi_bytes = TeXJob(StringInputSource("Hello!"), DviDevice(), options=TeXOptions()).run() with open("output.dvi", "wb") as f: f.write(dvi_bytes) ``` ### SvgDevice `SvgDevice` renders each typeset page as an SVG vector graphic. After the job runs, `get_all_pages()` returns the list of per-page SVG byte strings: ```python from aspose_tex import TeXJob, TeXOptions, SvgDevice, StringInputSource device = SvgDevice() TeXJob(StringInputSource("Hello!"), device, options=TeXOptions()).run() for i, svg in enumerate(device.get_all_pages()): with open(f"page_{i}.svg", "wb") as f: f.write(svg) ``` --- ## Input Sources ### FileInputSource `FileInputSource` reads TeX markup from a `.tex` file on disk. This is the standard input mode when typesetting existing documents: ```python from aspose_tex import TeXJob, TeXOptions, PdfDevice, FileInputSource pdf_bytes = TeXJob(FileInputSource("document.tex"), PdfDevice(), options=TeXOptions()).run() ``` ### StringInputSource `StringInputSource` accepts TeX markup as a Python string. This input mode is used for dynamic markup generation — constructing TeX programmatically and typesetting it without writing to disk: ```python from aspose_tex import TeXJob, TeXOptions, PdfDevice, StringInputSource tex = "Hello, world!" pdf_bytes = TeXJob(StringInputSource(tex), PdfDevice(), options=TeXOptions()).run() ``` --- ## Combining Components The three components work together to form a complete typesetting pipeline. Select the input source that matches your data flow and the device that matches your output format: ```python from aspose_tex import TeXJob, TeXOptions, SvgDevice, FileInputSource device = SvgDevice() TeXJob(FileInputSource("report.tex"), device, options=TeXOptions()).run() pages = device.get_all_pages() print(f"{len(pages)} SVG pages produced") ``` --- ## Tips and Best Practices - Use `StringInputSource` for short or dynamically generated TeX fragments; use `FileInputSource` when working with existing `.tex` files. - `PdfDevice` is the most portable output format; use `SvgDevice` when embedding TeX output in web pages or vector graphics workflows. - Reuse `TeXOptions` instances across jobs if processing multiple documents with the same settings. - The `run()` return value is `bytes` for PDF and DVI; for SVG, the bytes are retrieved from `SvgDevice.get_all_pages()` after the job completes. --- ## API Reference Summary | Class | Role | |-------|------| | `TeXJob` | Entry point; drives the TeX typesetting pipeline | | `TeXOptions` | Engine configuration; defaults work for most documents | | `PdfDevice` | Output device producing PDF bytes | | `DviDevice` | Output device producing DVI bytes | | `SvgDevice` | Output device producing per-page SVG via `get_all_pages()` | | `FileInputSource` | Input from a `.tex` file on disk | | `StringInputSource` | Input from a Python string | ## See Also - [Aspose.TeX FOSS for Python — Open-Source TeX Engine](https://products.aspose.org/tex/python/) - [Developer Guide](https://docs.aspose.org/tex/python/developer-guide/) - [API Reference](https://reference.aspose.org/tex/python/) ## Getting Started - [Getting Started](https://docs.aspose.org/tex/python/getting-started/) - [Developer Guide](https://docs.aspose.org/tex/python/developer-guide/) - [KB Articles](https://kb.aspose.org/tex/python/) - [API Reference](https://reference.aspose.org/tex/python/) ## Related Resources - [Aspose.TeX — Enterprise Blog](https://blog.aspose.com/) --- # Introducing Aspose.Words FOSS for .NET URL: https://blog.aspose.org/words/net/introducing-words-foss-net/ Aspose.Words FOSS for .NET is a free, MIT-licensed .NET library for creating, reading, and editing Word documents in pure C#, built from the genuine Aspose.Words engine. It reads and writes DOCX, DOCM, DOTX, DOTM, and Flat OPC files, converts to and from Markdown and plain text, and targets .NET Standard 2.0 with no native dependencies. --- Product: Aspose.Words Platform: net Page Type: index Canonical URL: https://blog.aspose.org/words/net/introducing-words-foss-net/ --- # Introducing Aspose.Words FOSS for .NET ## Introduction Aspose.Words FOSS for .NET is now available: a free, open-source .NET library for creating, reading, and editing Word documents in pure C#, with no Microsoft Word installation required. It is aimed at developers who need to generate reports and letters from templates, read and restructure content out of existing `.docx` files, or convert Word documents to Markdown or plain text as part of a processing pipeline, without licensing a commercial SDK to do it. The library is released under the MIT license and has no native dependencies — everything runs in managed code. It targets .NET Standard 2.0, so it works on .NET Framework 4.6.2+ and .NET 6, 8, and 10, on Windows, Linux, and macOS. Install it via NuGet, or build the library from source with a single `dotnet build` command (see Quick Start below). What sets this apart from a typical new open-source document library is that it is not a rewrite or a wrapper. Aspose.Words FOSS for .NET is the genuine Aspose.Words codebase — the same document engine that has processed Word documents in production since 2003 — reduced down to a free, MIT-licensed core. Developers who outgrow this edition and need page layout, rendering, or the additional format converters can move to the commercial [Aspose.Words for .NET](https://products.aspose.com/words/net/) without rewriting their code, since it is the same underlying API. --- ## Key Features ### Document Creation and Editing Build documents from scratch with `new Document()` and the high-level `DocumentBuilder`, or open existing `.docx` files with `new Document(fileName)`. `DocumentBuilder` provides sequential authoring methods such as `Write()`, `Writeln()`, `InsertParagraph()`, and `InsertBreak()`, along with formatting properties (`Font`, `ParagraphFormat`, `PageSetup`) that apply to content as it is inserted. For lower-level access, walk the document tree directly through `Section`, `Paragraph`, `Run`, and `Table` nodes, or subclass `DocumentVisitor` to process every node type in a single pass. ### Tables and Lists Tables are built from `Table`, `Row`, and `Cell` nodes. `Table.SetBorders()`, `Table.SetShading()`, and `Table.AutoFit()` format an entire table at once, while `Table.Rows` and per-row `Cell` access give finer control. Numbered and bulleted lists go through `ListCollection` and `ListFormat`: apply a built-in style with `ListFormat.ApplyBulletDefault()` or `ApplyNumberDefault()`, or register a custom list definition with `ListCollection.Add()`. ### Tracked Changes and Document Protection Call `Document.StartTrackRevisions()` before editing to record insertions, deletions, and formatting changes, then inspect, accept, or reject them through `RevisionCollection` (`AcceptAll()`, `RejectAll()`, `Accept(criteria)`, `Reject(criteria)`), or accept everything at once with `Document.AcceptAllRevisions()`. `Document.Protect()` applies password protection or read-only enforcement using the `DocumentSecurity` enum (`ReadOnlyEnforced`, `ReadOnlyRecommended`, `PasswordProtected`, and related values), and `Document.Unprotect()` reverses it. ### Fields, Macros, and Digital Signatures The field evaluation engine updates fields such as `FieldDate` (the `DATE` field) and `FieldDocProperty` (the `DOCPROPERTY` field) in place through `Document.UpdateFields()` — fields that depend on page layout, such as page numbers, evaluate to placeholder values since page layout is not part of this edition. DOCM and DOTM files round-trip with their VBA projects intact. Existing digital signatures can be inspected through `DigitalSignatureCollection` and `DigitalSignature` (`IsValid`, `SubjectName`, `IssuerName`, `SignTime`) to confirm whether a document is signed and has not been tampered with; creating new signatures is not part of this edition. ### Charts Insert a chart into a document with `DocumentBuilder.InsertChart()`, then configure its data series through the returned `Chart` object. ```csharp using Aspose.Words; using Aspose.Words.Drawing.Charts; Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); Shape shape = builder.InsertChart(ChartType.Line, 432, 252); Chart chart = shape.Chart; // Delete default generated series. chart.Series.Clear(); string[] categories = new string[] { "AW Category 1", "AW Category 2", "AW Category 3" }; chart.Series.Add("AW Series 1", categories, new double[] { 4.3, 2.5, 3.5 }); doc.Save("chart.docx"); ``` --- ## Quick Start Aspose.Words FOSS for .NET is available via NuGet: To build from source instead: ```bash git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git cd Aspose.Words-FOSS-for-.NET dotnet build Aspose.Words.sln -c Release ``` Then add a project reference to `Aspose.Words.csproj` from your application. With the reference in place, create a document with a chart and save it to DOCX: ```csharp using Aspose.Words; using Aspose.Words.Drawing.Charts; Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); Shape shape = builder.InsertChart(ChartType.Line, 432, 252); Chart chart = shape.Chart; // Delete default generated series. chart.Series.Clear(); string[] categories = new string[] { "AW Category 1", "AW Category 2", "AW Category 3" }; chart.Series.Add("AW Series 1", categories, new double[] { 4.3, 2.5, 3.5 }); doc.Save("chart.docx"); Console.WriteLine("Saved chart.docx"); ``` --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | DOCX | .docx | ✓ | ✓ | | DOCM | .docm | ✓ | ✓ | | DOTX | .dotx | ✓ | ✓ | | DOTM | .dotm | ✓ | ✓ | | Flat OPC (all variants) | (various) | ✓ | ✓ | | Markdown | .md | ✓ | ✓ | | Text | .txt | ✓ | ✓ | This edition intentionally excludes page layout and rendering — no PDF, XPS, or image export, and no printing, which also means layout-dependent field values such as page numbers evaluate to placeholders rather than being computed. The additional format converters (DOC, RTF, ODT, HTML, EPUB, MHTML, MOBI, AZW3, and WordML) are not read or written, and mail merge execution, LINQ Reporting, document comparison, creating new digital signatures, and embedded-font subsetting are not included. These are the same subsystems removed from the commercial codebase to keep this edition free. --- ## Open Source & Licensing Aspose.Words FOSS for .NET is released under the MIT license, free for both commercial and personal use with no royalties or redistribution restrictions. The full source is available on GitHub in the [Aspose.Words FOSS for .NET repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET). --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/net/getting-started/) - [Developer Guide](https://docs.aspose.org/words/net/developer-guide/) - [KB Articles](https://kb.aspose.org/words/net/) - [API Reference](https://reference.aspose.org/words/net/) - [GitHub Repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/) --- # Building Charts in Word Documents with Aspose.Words FOSS for .NET URL: https://blog.aspose.org/words/net/words-charts-in-net/ Aspose.Words FOSS for .NET creates native Word charts through the Chart object model reached from DocumentBuilder.InsertChart — bar, line, pie, scatter, and dozens of other chart types, each with its own series, axes, legend, data table, and formatting. This deep dive walks through the ChartSeries, ChartAxis, ChartLegend, and ChartDataLabel APIs with a working C# example. --- Product: Aspose.Words Platform: net Page Type: index Canonical URL: https://blog.aspose.org/words/net/words-charts-in-net/ --- # Building Charts in Word Documents with Aspose.Words FOSS for .NET ## Introduction This guide shows how to build native Word charts with Aspose.Words FOSS for .NET — the same drawing objects Word itself creates when you use Insert > Chart — entirely from code. A chart added this way is not a picture; it is a `Chart` object embedded in the document's OOXML package, with a data series model, axes, a legend, and a data table that Word can still open and edit after the file is saved. This post is a deep dive into that Chart API: how to create a chart, add series data, and reach the axis, legend, data label, and formatting objects that control how it renders. The library is MIT-licensed and has no native dependencies. It targets .NET Standard 2.0, so the code in this post runs unchanged on .NET Framework 4.6.2+ and .NET 6, 8, and 10. Install it via NuGet, or build it from source — see Quick Start below. Everything shown here is the same chart engine used by the commercial [Aspose.Words for .NET](https://products.aspose.com/words/net/); this edition includes the full chart object model but not page layout or rendering, so a chart's on-page position is not computed and the document cannot be exported to PDF or an image. --- ## What's Included ### Creating a Chart and Adding a Data Series `DocumentBuilder.InsertChart(chartType, width, height)` inserts a chart shape at the current position and returns a `Shape`; its `Chart` property is the entry point for everything else. A newly inserted chart already has a default series, so most code clears it first and adds its own data through `Chart.Series`, a `ChartSeriesCollection`. ```csharp using Aspose.Words; using Aspose.Words.Drawing.Charts; Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); Shape shape = builder.InsertChart(ChartType.Line, 432, 252); Chart chart = shape.Chart; // Delete default generated series. chart.Series.Clear(); string[] categories = new string[] { "AW Category 1", "AW Category 2", "AW Category 3" }; chart.Series.Add("AW Series 1", categories, new double[] { 4.3, 2.5, 3.5 }); ``` `ChartSeriesCollection.Add` has overloads for category/value pairs (as above), X/Y value pairs, dated series, and bubble series with an extra size value. On an individual `ChartSeries`, `Add(xValue)`, `Add(xValue, yValue)`, and `Add(xValue, yValue, bubbleSize)` append single points, `Insert` places a point at a given index, and `Clear()` / `ClearValues()` remove series data without necessarily removing the series object itself. ### Chart Types and Series Types `ChartType` — the enum passed to `InsertChart` — has around 40 members covering the standard Word chart families: `Line`, `Bar`, `Column`, `Pie`, `Doughnut`, `Radar`, `Scatter`, `Stock`, `Surface`, `Treemap`, `Sunburst`, `Histogram`, `Pareto`, `BoxAndWhisker`, `Waterfall`, and `Funnel`, plus stacked, percent-stacked, and 3D variants of several of them (`Bar3D`, `ColumnStacked`, `Area3DPercentStacked`, and so on). A related but distinct enum, `ChartSeriesType`, appears on `ChartSeries.SeriesType` and `ChartSeriesGroup.SeriesType` and describes the type of an individual series or series group rather than the chart as a whole. It carries the same members as `ChartType` plus two more — `ParetoLine` and `RegionMap` — that `ChartType` doesn't expose directly. `ChartSeriesGroup` is what makes combo charts possible: `Chart.SeriesGroups` (a `ChartSeriesGroupCollection`) holds one group per series type in the chart, and each group has its own `AxisX`/`AxisY` pair and layout properties such as `Overlap`, `GapWidth`, `BubbleScale`, and `DoughnutHoleSize`. ### Axes, Gridlines, and Scaling `Chart.AxisX`, `AxisY`, and `AxisZ` (plus the `Axes` collection) return `ChartAxis` objects. Each axis has a `Type` (`ChartAxisType.Category`, `Series`, or `Value`), tick mark settings (`MajorTickMark`, `MinorTickMark` — `Cross`, `Inside`, `Outside`, or `None`), gridline flags (`HasMajorGridlines`, `HasMinorGridlines`), and unit control (`MajorUnit`, `MinorUnit`, and their `*IsAuto` counterparts). `ChartAxis.Scaling` returns an `AxisScaling` object whose `Minimum` and `Maximum` are `AxisBound` values — `AxisBound.IsAuto` reports whether the bound is computed automatically, and the parameterized constructors (`AxisBound(value)`, `AxisBound(datetime)`) set an explicit numeric or date bound. A category axis can be pinned to text or time categories through `ChartAxis.CategoryType` (`AxisCategoryType.Automatic`, `Category`, or `Time`), and `ChartAxis.Title` exposes a `ChartAxisTitle` with its own `Text`, `Show`, and `Font`. ### Legend, Data Table, and Chart Title `Chart.Legend` returns a `ChartLegend`, whose `Position` (a `LegendPosition` of `None`, `Bottom`, `Left`, `Right`, `Top`, or `TopRight`) controls where it renders relative to the plot area; `LegendEntries` is a `ChartLegendEntryCollection` of individual `ChartLegendEntry` objects, each with its own `Font` and `IsHidden` flag for hiding a single series from the legend without removing it from the chart. `Chart.DataTable` (a `ChartDataTable`) renders the series values as a grid beneath the chart when `Show` is set, with `HasLegendKeys`, `HasHorizontalBorder`, `HasVerticalBorder`, and `HasOutlineBorder` controlling its appearance. `Chart.Title` is a `ChartTitle` with `Text` and `Show` properties, following the same pattern as the axis titles. ### Data Labels, Data Points, and Markers `ChartSeries.HasDataLabels` turns on data labels for a series, and `ChartSeries.DataLabels` (a `ChartDataLabelCollection`) or an individual `ChartDataLabel` from it controls what each label shows: `ShowValue`, `ShowCategoryName`, `ShowSeriesName`, `ShowPercentage`, `ShowLegendKey`, and `ShowBubbleSize` are independent flags, and `Position` (`ChartDataLabelPosition.Center`, `InsideEnd`, `OutsideEnd`, `BestFit`, and others) places the label relative to its point. `ChartSeries.DataPoints` gives per-point access through `ChartDataPoint`, which carries its own `Marker` (a `ChartMarker` with `Symbol` from the `MarkerSymbol` enum and a `Size`), `Explosion` (for pulling out a pie slice), and `Format`. Every chart element that can be filled or outlined — series, data points, the legend, the title, the data table — exposes a `ChartFormat` through its `Format` property, with `Fill`, `Stroke`, and `ShapeType` (`ChartShapeType`) properties and a `SetDefaultFill()` method to reset it. One caveat worth knowing: the theme-linked variants of fill and stroke color on `ChartFormat` (`FillableForeThemeColor`, `FillableBackThemeColor`, `StrokeForeThemeColor`, `StrokeBackThemeColor`, and their tint/shade counterparts) are not implemented in this edition — set plain `Fill`/`Stroke` colors instead of theme-color references. `Chart.Style` (a `ChartStyle` such as `Muted`, `Saturated`, `Gradient`, `Outline`, or `Black`) applies a predefined look to the whole chart in one step. --- ## Quick Start Aspose.Words FOSS for .NET is available via NuGet: To build from source instead: ```bash git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git cd Aspose.Words-FOSS-for-.NET dotnet build Aspose.Words.sln -c Release ``` Then add a project reference to `Aspose.Words.csproj` from your application. With the reference in place, this creates a line chart with one series and saves it to DOCX: ```csharp using Aspose.Words; using Aspose.Words.Drawing.Charts; Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); Shape shape = builder.InsertChart(ChartType.Line, 432, 252); Chart chart = shape.Chart; // Delete default generated series. chart.Series.Clear(); string[] categories = new string[] { "AW Category 1", "AW Category 2", "AW Category 3" }; chart.Series.Add("AW Series 1", categories, new double[] { 4.3, 2.5, 3.5 }); doc.Save("chart.docx"); Console.WriteLine("Saved chart.docx"); ``` Open `chart.docx` in Word and the chart is fully editable — right-click it and choose "Edit Data" to see the same three categories and values written above. --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | DOCX | .docx | ✓ | ✓ | | DOCM | .docm | ✓ | ✓ | | DOTX | .dotx | ✓ | ✓ | | DOTM | .dotm | ✓ | ✓ | | Flat OPC (all variants) | (various) | ✓ | ✓ | | Markdown | .md | ✓ | ✓ | | Text | .txt | ✓ | ✓ | Charts built with the Chart API are OOXML drawing objects, so they round-trip across the DOCX-family formats above (DOCX, DOCM, DOTX, DOTM, and Flat OPC). This edition cannot export to PDF, XPS, or images and cannot print, so nothing renders a chart to a bitmap — the chart stays a live, editable object inside the Word file. The additional format converters removed from this edition (DOC, RTF, ODT, HTML, EPUB, MHTML, MOBI, AZW3, and WordML) are the same subsystems excluded everywhere else in the library, not something specific to charts. --- ## Open Source & Licensing Aspose.Words FOSS for .NET is released under the MIT license, free for commercial and personal use with no royalties or redistribution restrictions. The full source, including the chart classes referenced in this post, is available on GitHub in the [Aspose.Words FOSS for .NET repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET). --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/net/getting-started/) - [Developer Guide](https://docs.aspose.org/words/net/developer-guide/) - [KB Articles](https://kb.aspose.org/words/net/) - [API Reference](https://reference.aspose.org/words/net/) - [GitHub Repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/) --- # Working with the Document Object Model in Aspose.Words FOSS for .NET URL: https://blog.aspose.org/words/net/words-document-net/ Aspose.Words FOSS for .NET represents a Word document as a tree of Node objects — sections, paragraphs, runs, and tables — built and navigated through DocumentBuilder, the node-tree APIs, and DocumentVisitor. This guide covers building and editing content with DocumentBuilder, walking and mutating the node tree, visitor-based processing, find-and-replace, and combining or cloning documents. --- Product: Aspose.Words Platform: net Page Type: index Canonical URL: https://blog.aspose.org/words/net/words-document-net/ --- # Working with the Document Object Model in Aspose.Words FOSS for .NET ## Introduction This guide looks at how Aspose.Words FOSS for .NET represents a Word document in memory, and at the APIs used to build, navigate, and change that representation: DocumentBuilder for sequential authoring, the node tree (Node, CompositeNode, NodeCollection) for direct structural access, DocumentVisitor for processing every node type in one pass, find-and-replace via Range and FindReplaceOptions, and the methods for combining and cloning documents. Where [the announcement post](/words/net/introducing-words-foss-net/) introduces the library as a whole, this one stays focused on the document object model (DOM) — the single largest area of the API surface — and how its pieces fit together. Aspose.Words FOSS for .NET is released under the MIT license with no native dependencies; it targets .NET Standard 2.0, so the DOM described here is available on .NET Framework 4.6.2+ and .NET 6, 8, and 10, on Windows, Linux, and macOS. Install it via NuGet, or build it from source — see Quick Start below. Every task described below — writing a report from scratch, restructuring an existing `.docx` file, walking its contents for analysis, or assembling several documents into one — starts from the same handful of base types: `Document`, `DocumentBuilder`, and the `Node` hierarchy underneath them. --- ## The Document Object Model ### Building Documents with DocumentBuilder `DocumentBuilder` is a cursor-based writer that sits on top of a `Document` and inserts content sequentially. `Write(text)` and `Writeln(text)` add text at the current position; `InsertParagraph()` and `InsertBreak(breakType)` add paragraph and page/column/section breaks. Formatting is stateful: the builder's `Font`, `ParagraphFormat`, `ListFormat`, and `PageSetup` properties apply to everything written afterward, and `PushFont()` / `PopFont()` save and restore the current font state so a temporary style change does not have to be undone by hand. Navigation methods reposition the cursor anywhere in an existing document — `MoveToDocumentStart()`, `MoveToDocumentEnd()`, `MoveToSection(sectionIndex)`, `MoveToBookmark(bookmarkName)`, `MoveToParagraph(paragraphIndex, characterIndex)`, and the general-purpose `MoveTo(node)` — and `DocumentBuilder.CurrentNode`, `DocumentBuilder.CurrentParagraph`, and `DocumentBuilder.CurrentSection` report where the builder currently sits. For read-only text extraction where a full DOM is not needed, `PlainTextDocument` offers a lighter path: `new PlainTextDocument(fileName)` exposes just the `PlainTextDocument.Text` property and the document's built-in and custom properties. ### The Node Tree: Sections, Paragraphs, Runs, and Tables A `Document` is a tree of `Node` objects rooted at the document itself: `Section` → `Body` → `Paragraph` → `Run` for body text, with `Table` → `Row` → `Cell` branching off wherever a table appears. `CompositeNode`, the base class for every container node, exposes `CompositeNode.FirstChild`, `CompositeNode.LastChild`, `Node.NextSibling`, and `Node.PreviousSibling` for direct traversal, `GetChildNodes(nodeType, isDeep)` to collect every node of a given `NodeType` (`Paragraph`, `Run`, `Table`, and so on) at any depth, and `GetChild(nodeType, index, isDeep)` for indexed lookups. `AppendChild(newChild)`, `InsertBefore(newChild, refChild)`, `InsertAfter(newChild, refChild)`, and `RemoveChild(oldChild)` mutate the tree directly. `CompositeNode.SelectNodes(xpath)` and `SelectSingleNode(xpath)` select nodes with an XPath-style expression instead of walking the tree by hand, and for very large documents, `Node.NextPreOrder(rootNode)` / `PreviousPreOrder(rootNode)` step through every node one at a time without recursion. ### DocumentVisitor: Processing Every Node Type in One Pass Subclassing `DocumentVisitor` is the way to process a document without hard-coding its structure. It defines paired Visit-Start / Visit-End methods for every composite node type, including `DocumentVisitor.VisitSectionStart`, `DocumentVisitor.VisitParagraphStart`, `DocumentVisitor.VisitTableStart`, `DocumentVisitor.VisitRowStart`, `DocumentVisitor.VisitCellStart`, and `DocumentVisitor.VisitBookmarkStart` — each with a matching End callback — plus `DocumentVisitor.VisitFieldStart`, `DocumentVisitor.VisitFieldSeparator`, `DocumentVisitor.VisitFieldEnd`, and `DocumentVisitor.VisitRun` for individual text runs. Call `Accept(visitor)` on a `Document`, `Section`, or any other node to run the visitor over that node and everything beneath it; `AcceptStart(visitor)` and `AcceptEnd(visitor)` invoke only the entry and exit callbacks for a single composite node. Each Visit method returns a `VisitorAction` value that controls how traversal continues — Continue into the subtree, SkipThisNode to skip it, or Stop to halt entirely. ### Finding and Replacing Text `Range.Replace(pattern, replacement)` runs a find-and-replace over the `Range` that owns it — an entire `Document`, a `Section`, or any node's own `Range` property — with the search pattern accepted as either a literal string or a regular expression. The `Range.Replace(pattern, replacement, options)` overload takes a `FindReplaceOptions` instance to control `FindReplaceOptions.MatchCase`, `FindReplaceOptions.FindWholeWordsOnly`, search `FindReplaceOptions.Direction` (a `FindReplaceDirection` value of Forward or Backward), formatting applied to replacement text (`FindReplaceOptions.ApplyFont`, `FindReplaceOptions.ApplyParagraphFormat`), and which surrounding content to leave alone (`FindReplaceOptions.IgnoreFields`, `FindReplaceOptions.IgnoreFootnotes`, `FindReplaceOptions.IgnoreFieldCodes`, and related Ignore* flags). For per-match logic beyond a simple substitution, implement the `Replacing(args)` method of `IReplacingCallback` and assign the implementation to `FindReplaceOptions.ReplacingCallback`; each match calls back with a `ReplacingArgs` describing the match, and the return value of the callback — a `ReplaceAction` value of Replace, Skip, or Stop — decides what happens to it. ### Combining and Cloning Documents `Document.AppendDocument(srcDoc, importFormatMode)` appends the full content of one `Document` onto the end of another. Its importFormatMode argument — an `ImportFormatMode` value of UseDestinationStyles, KeepSourceFormatting, or KeepDifferentStyles — decides how style conflicts between the source and destination are resolved, and the `Document.AppendDocument(srcDoc, importFormatMode, importFormatOptions)` overload adds finer control through `ImportFormatOptions` (`ImportFormatOptions.KeepSourceNumbering`, `ImportFormatOptions.IgnoreHeaderFooter`, `ImportFormatOptions.MergePastedLists`, and similar flags). To insert another document's content at a specific position instead of the end, `DocumentBuilder.InsertDocument(srcDoc, importFormatMode, importFormatOptions)` does the equivalent from the builder's current cursor position, and `DocumentBuilder.InsertDocumentInline(srcDoc, importFormatMode, importFormatOptions)` inserts the same content without adding a paragraph or section break at the insertion point. `Document.ImportNode(srcNode, isImportChildren)` copies one node — optionally with its children — from a different document so it can be appended into the current one, and the `Node.Clone(isCloneChildren)` method available on any node duplicates structure within the same document, such as reusing a `Section` as a template for repeated content. ### Bookmarks and Document Variables The `Range.Bookmarks` property exposes a `BookmarkCollection` of named anchors within that range. `DocumentBuilder.StartBookmark(bookmarkName)` and `EndBookmark(bookmarkName)` mark a bookmark's extent while building; the `BookmarkCollection` indexer, `bookmarks[name]`, retrieves one later for `DocumentBuilder.MoveToBookmark(bookmarkName)` navigation or for reading `Bookmark.Text`. Separately, `Document.Variables` — a `VariableCollection` — stores arbitrary name/value string pairs directly on the document itself, useful for carrying small pieces of state through a document-generation pipeline without adding visible content. --- ## Quick Start Aspose.Words FOSS for .NET is available via NuGet: To build from source instead: ```bash git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git cd Aspose.Words-FOSS-for-.NET dotnet build Aspose.Words.sln -c Release ``` With a project reference to Aspose.Words.csproj in place, the shortest path to a document follows the same pattern used throughout this post: construct a `Document`, wrap it in a `DocumentBuilder`, call `Write()` or `Writeln()` to add text — formatting set on the builder's `Font` and `ParagraphFormat` properties carries into every subsequent write — and call `Document.Save(fileName)` to write it out as `.docx`, `.docm`, `.dotx`, `.dotm`, Flat OPC, Markdown, or plain text. To edit an existing file instead of starting from scratch, load it directly with `new Document(fileName)`, move the builder to a specific location with `MoveToBookmark()`, `MoveToParagraph()`, or `MoveTo(node)`, and continue writing from there. --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | DOCX | .docx | ✓ | ✓ | | DOCM | .docm | ✓ | ✓ | | DOTX | .dotx | ✓ | ✓ | | DOTM | .dotm | ✓ | ✓ | | Flat OPC (all variants) | (various) | ✓ | ✓ | | Markdown | .md | ✓ | ✓ | | Text | .txt | ✓ | ✓ | The node tree described above is available the same way regardless of which of these formats a document was loaded from or will be saved to — the DOM is format-independent internally. What is not included in this edition is anything that depends on page layout: no PDF, XPS, or image export, and no printing, so layout-dependent field values such as page numbers evaluate to placeholders rather than being computed. The additional format converters (DOC, RTF, ODT, HTML, EPUB, MHTML, MOBI, AZW3, and WordML) are not read or written, and mail merge execution, LINQ Reporting, and document comparison are not included. Developers who need those capabilities can move to the commercial [Aspose.Words for .NET](https://products.aspose.com/words/net/) without rewriting the DOM code shown here, since both editions share the same underlying API. --- ## Open Source & Licensing Aspose.Words FOSS for .NET is released under the MIT license, free for commercial and personal use with no royalties or redistribution restrictions. The source, including the `Document`, `DocumentBuilder`, and node-tree implementation described above, is available in the [Aspose.Words FOSS for .NET repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET) on GitHub. --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/net/getting-started/) - [Developer Guide](https://docs.aspose.org/words/net/developer-guide/) - [KB Articles](https://kb.aspose.org/words/net/) - [API Reference](https://reference.aspose.org/words/net/) - [GitHub Repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/) --- # Text Formatting and Find-and-Replace in Aspose.Words FOSS for .NET URL: https://blog.aspose.org/words/net/words-text-in-net/ Aspose.Words FOSS for .NET exposes Font, ParagraphFormat, ListFormat, and FrameFormat for run-level, paragraph-level, and list-level text formatting, plus Range.Replace and IReplacingCallback for regex-based find-and-replace. This deep dive on the free, MIT-licensed .NET Standard 2.0 library walks through character formatting, paragraph and list control, text frames, and custom replace logic. --- Product: Aspose.Words Platform: net Page Type: index Canonical URL: https://blog.aspose.org/words/net/words-text-in-net/ --- # Text Formatting and Find-and-Replace in Aspose.Words FOSS for .NET ## Introduction Aspose.Words FOSS for .NET includes the same text-formatting object model as the commercial Aspose.Words engine: `Font` for run-level attributes, `ParagraphFormat` for paragraph-level attributes, `ListFormat` for numbered and bulleted lists, `FrameFormat` for positioned text frames, and `Range.Replace` for find-and-replace. This guide looks specifically at that layer — formatting and rewriting text that already exists in a document — rather than at building a document's structure from scratch (see the [introduction post](/words/net/introducing-words-foss-net/) for an overview of the release). The library is MIT-licensed with no native dependencies and targets .NET Standard 2.0, so it runs on .NET Framework 4.6.2+ and .NET 6, 8, and 10. Install it via NuGet, or build it from source (see Quick Start below). Everything described here works against `.docx`, `.docm`, `.dotx`, `.dotm`, and Flat OPC files loaded with `new Document(fileName)`, or against documents built in memory with `DocumentBuilder`. Because Aspose.Words FOSS for .NET is the genuine Aspose.Words codebase reduced to a free core rather than a rewrite, the `Font`, `ParagraphFormat`, `ListFormat`, and `FrameFormat` object model carries over directly to the commercial [Aspose.Words for .NET](https://products.aspose.com/words/net/) if a project later needs page layout, rendering, or the additional format converters that this edition excludes. --- ## Key Features ### Run-Level Formatting with Font Every `Run` exposes a `Font` property, and `DocumentBuilder.Font` sets the font that will be applied to text written next. Besides the obvious `Bold`, `Italic`, and `Underline` (an `Underline` enum with values including `Single`, `Double`, `Dotted`, `Dash`, `Wavy`, and their `*Heavy` variants), `Font` covers `StrikeThrough`, `DoubleStrikeThrough`, `Superscript`, `Subscript`, `SmallCaps`, `AllCaps`, `Hidden`, `Shadow`, `Outline`, `Emboss`, `Engrave`, `Color`, `HighlightColor`, `Spacing`, `Position`, `Kerning`, `Scaling`, and `EmphasisMark`. `Font.Style`, `Font.StyleName`, and `Font.StyleIdentifier` tie a run back to a character style, and `Font.ClearFormatting()` resets direct formatting on a run back to its style defaults. `DocumentBuilder` also exposes `Bold`, `Italic`, and `Underline` directly as shortcuts, plus `PushFont()` and `PopFont()` to save and restore the builder's current font state around a temporary formatting change. ### Paragraph Formatting with ParagraphFormat `ParagraphFormat` (reachable through `Paragraph.ParagraphFormat` or `DocumentBuilder.ParagraphFormat`) controls alignment through the `ParagraphAlignment` enum (`Left`, `Center`, `Right`, `Justify`, `Distributed`, plus Arabic kashida and Thai-distributed variants), indentation through `LeftIndent`, `RightIndent`, and `FirstLineIndent` (with `CharacterUnit*` equivalents for East Asian layouts), and spacing through `SpaceBefore`, `SpaceAfter`, and `LineSpacingRule`/`LineSpacing`. Pagination behavior is controlled with `KeepTogether`, `KeepWithNext`, `PageBreakBefore`, and `WidowControl`, and `Bidi` marks a paragraph as right-to-left. Custom tab stops live in `ParagraphFormat.TabStops`, a `TabStopCollection` of `TabStop` objects, each with a `Position`, a `TabAlignment` (`Left`, `Center`, `Right`, `Decimal`, `Bar`), and a `TabLeader` (`None`, `Dots`, `Dashes`, `Line`, `Heavy`, `MiddleDot`). As with `Font`, `ParagraphFormat.Style` and `StyleName` link the paragraph to a named `Style`, and `ClearFormatting()` clears direct paragraph formatting. ### Lists with ListFormat `ListFormat` (on `Paragraph.ListFormat` or `DocumentBuilder.ListFormat`) applies list formatting to a paragraph: `ApplyBulletDefault()` and `ApplyNumberDefault()` switch it to a default bulleted or numbered list, `RemoveNumbers()` removes list formatting entirely, and `ListIndent()`/`ListOutdent()` move it between list levels. `ListFormat.List` returns the underlying `List` definition, and `ListFormat.ListLevel` returns the `ListLevel` in effect for that paragraph, which carries per-level settings such as `NumberStyle`, `NumberFormat`, `Alignment` (a `ListLevelAlignment` of `Left`, `Center`, or `Right`), `StartAt`, `RestartAfterLevel`, a level-specific `Font`, and `TrailingCharacter` (a `ListTrailingCharacter` of `Tab`, `Space`, or `Nothing`) controlling the gap between the list label and the paragraph text. New list definitions come from `ListCollection.Add(listTemplate)` using one of the built-in `ListTemplate` presets (`BulletDefault`, `NumberArabicDot`, `NumberUppercaseRomanDot`, and similar), or `AddSingleLevelList` for a single-level list; a document's lists are enumerated through `Document.Lists`. ### Text Frames with FrameFormat `Paragraph.FrameFormat` is a read-only reporting object: every property on it reflects a paragraph's *current* frame state rather than letting you set it directly. `IsFrame` reports whether the paragraph is currently a frame; `Width`, `Height`, and `HeightRule` report its size; `HorizontalPosition` and `VerticalPosition`, together with `RelativeHorizontalPosition` and `RelativeVerticalPosition`, report where it is anchored relative to the page, margin, column, or paragraph; and `HorizontalDistanceFromText`/`VerticalDistanceFromText` report the gap between the frame and the surrounding body text. `HorizontalAlignment` and `VerticalAlignment` report how content aligns within the frame. ### Find and Replace with Range and IReplacingCallback `Range.Replace` — available on `Document.Range` for a whole-document pass, or on the `Range` of any node — has overloads for a plain pattern/replacement pair and for a pattern/replacement pair combined with a `FindReplaceOptions` instance, supporting regex-based matching. `FindReplaceOptions.MatchCase` and `FindWholeWordsOnly` narrow what counts as a match; `Direction` (`FindReplaceDirection.Forward` or `Backward`) sets scan order; `ApplyFont` and `ApplyParagraphFormat` let a replace pass carry formatting onto the replacement text; and a set of `Ignore*` flags (`IgnoreDeleted`, `IgnoreInserted`, `IgnoreFields`, `IgnoreFieldCodes`, `IgnoreFootnotes`, `IgnoreStructuredDocumentTags`, `IgnoreShapes`, `IgnoreOfficeMath`) exclude specific content categories from the match. For replacement logic that a fixed string can't express, implement `IReplacingCallback.Replacing(args)` and set it as `FindReplaceOptions.ReplacingCallback` (or pass it to one of the `FindReplaceOptions` constructors that accepts a callback directly); the `args` parameter is a `ReplacingArgs` exposing `Match`, `MatchNode`, `MatchOffset`, and a settable `Replacement` string so the callback can compute a value per match. A related `ReplaceAction` enum (`Replace`, `Skip`, `Stop`) describes the possible outcomes for a single match during the operation. --- ## Quick Start Aspose.Words FOSS for .NET is available via NuGet: To build from source instead: ```bash git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git cd Aspose.Words-FOSS-for-.NET dotnet build Aspose.Words.sln -c Release ``` Then add a project reference to `Aspose.Words.csproj`. To format text as you author it, set `DocumentBuilder.Font` properties (`Bold`, `Italic`, `Underline`), `DocumentBuilder.ParagraphFormat` properties (`Alignment`, indents, spacing), and `DocumentBuilder.ListFormat` (`ApplyBulletDefault()`, `ApplyNumberDefault()`) before calling `Write()`, `Writeln()`, or `InsertParagraph()` — the builder applies its current formatting state to everything written until you change it again, or wrap a temporary change in `PushFont()`/`PopFont()`. To reformat or rewrite text already in a document, open it with `new Document(fileName)` and call `Range.Replace()` on `doc.Range` — either the plain pattern/replacement overload, or the overload that takes a `FindReplaceOptions` with `MatchCase`, `FindWholeWordsOnly`, or a custom `IReplacingCallback` — then `Save()` the result. --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | DOCX | .docx | ✓ | ✓ | | DOCM | .docm | ✓ | ✓ | | DOTX | .dotx | ✓ | ✓ | | DOTM | .dotm | ✓ | ✓ | | Flat OPC (all variants) | (various) | ✓ | ✓ | | Markdown | .md | ✓ | ✓ | | Text | .txt | ✓ | ✓ | The formatting classes above apply the same way regardless of which of these formats a document is loaded from or saved to. This edition does not support DOC, RTF, ODT, HTML, EPUB, MHTML, MOBI, AZW3, or WordML for reading or writing, and does not support PDF, XPS, or image export, since page layout and rendering are outside its scope. --- ## Open Source & Licensing Aspose.Words FOSS for .NET is released under the MIT license, free for commercial and personal use with no royalties or redistribution restrictions. The full source, including the `Font`, `ParagraphFormat`, `ListFormat`, `FrameFormat`, and `Range` implementations described above, is available on GitHub in the [Aspose.Words FOSS for .NET repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET). --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/net/getting-started/) - [Developer Guide](https://docs.aspose.org/words/net/developer-guide/) - [KB Articles](https://kb.aspose.org/words/net/) - [API Reference](https://reference.aspose.org/words/net/) - [GitHub Repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/) --- # Working with Shapes and Drawing Objects in Aspose.Words FOSS for .NET URL: https://blog.aspose.org/words/net/words-word-drawing-shapes-in-net/ Aspose.Words FOSS for .NET exposes the Word drawing layer through the Shape and ShapeBase classes, covering AutoShapes, text boxes, embedded pictures, and OLE objects. This deep dive walks through shape positioning, fill and stroke formatting, text wrapping, and picture data using the ShapeType, TextBox, ImageData, and Fill APIs. --- Product: Aspose.Words Platform: net Page Type: index Canonical URL: https://blog.aspose.org/words/net/words-word-drawing-shapes-in-net/ --- # Working with Shapes and Drawing Objects in Aspose.Words FOSS for .NET ## Introduction Word documents place images, text boxes, and other free-floating objects in a drawing layer that sits apart from the regular flow of paragraphs and tables. Aspose.Words FOSS for .NET exposes this drawing layer through the `Shape` and `ShapeBase` classes, giving programmatic access to the same AutoShape, picture, text box, and OLE object model that Word itself uses internally. This guide shows how the library represents and manipulates these drawing objects — positioning, fill and outline formatting, embedded pictures, and text laid out inside a shape — across DOCX, DOCM, DOTX, and DOTM documents. This is useful for code that builds report or letterhead templates with a positioned logo or graphic, generates documents with floating text boxes and callouts, or inspects shapes already present in an uploaded document — extracting an embedded picture's bytes, reading a signature line's signer name, or repositioning an existing image. Aspose.Words FOSS for .NET is released under the MIT license and targets .NET Standard 2.0, so it runs on .NET Framework 4.6.2+ and .NET 6, 8, and 10 with no native dependencies. Install it via NuGet, or build it from source (see Quick Start below). It is the same Aspose.Words document engine used commercially, not a rewrite or a wrapper, so the `Shape` and drawing-layer classes described here are the production API. --- ## Key Features ### The Shape and ShapeBase Object Model Every AutoShape, text box, embedded picture, OLE object, or ActiveX control anchored in a Word document is represented by the `Shape` class — sealed, and built on the abstract `ShapeBase` base class. Both share the same positioning and formatting surface: `Shape.Left`, `Shape.Top`, `Shape.Width`, `Shape.Height`, `Shape.Rotation`, and `Shape.ZOrder` for geometry, plus `Shape.IsGroup`, `Shape.IsImage`, `Shape.IsWordArt`, and `Shape.IsInline` flags describing what kind of object a given instance holds. The `ShapeType` enum enumerates the concrete shape kinds Word recognizes — Rectangle, Ellipse, Line, Arrow, a family of callout and connector types, TextBox, Image, and OleObject among more than eighty values — so code walking a document's shapes can branch on `Shape.ShapeType` to decide how to handle each one. Multiple shapes can be combined into a single `GroupShape`, itself a `ShapeBase` subclass, which keeps a set of shapes positioned and resized together; `DocumentBuilder.InsertGroupShape(shapes)` builds one from an existing array of shapes. ### Text Boxes and WordArt Any `Shape` can carry its own text through the `TextBox` class, exposed as `Shape.TextBox`. `TextBox` properties control how that text sits inside the shape: `TextBox.InternalMarginLeft`, `TextBox.InternalMarginRight`, `TextBox.InternalMarginTop`, and `TextBox.InternalMarginBottom` for padding, `TextBox.FitShapeToText` to let the shape grow with its content, `LayoutFlow` for text direction, `TextBoxWrapMode` for how text wraps inside the box, and `TextBox.VerticalAnchor` — a `TextBoxAnchor` value such as Top, Middle, BottomCentered, or TopBaseline — for vertical alignment. Linked text boxes, where overflow text continues into a second box, are modeled with `TextBox.Next` and `TextBox.Previous`. A related but distinct class, `TextPath`, defines WordArt-style text that follows a shape's outline instead of sitting inside it, with properties such as `TextPath.Text`, `TextPath.FontFamily`, `TextPath.Bold`, and `TextPath.RotateLetters`, plus a `TextPathAlignment` enum with values such as Stretch, Center, and LetterJustify. ### Pictures and Embedded Images When a shape holds a picture, `Shape.HasImage` is true and `Shape.ImageData` returns an `ImageData` object. `ImageData` exposes the raw bytes through `ImageData.ImageBytes`, the detected format through `ImageType` (values including Jpeg, Png, Bmp, Gif, Emf, Wmf, Pict, Eps, and WebP), pixel dimensions and resolution through `ImageSize`, and cropping via `ImageData.CropTop`, `ImageData.CropBottom`, `ImageData.CropLeft`, and `ImageData.CropRight`. Color adjustments — `ImageData.Brightness`, `ImageData.Contrast`, `ImageData.GrayScale`, `ImageData.BiLevel`, and `ImageData.ChromaKey` — are properties on the same object, and `ImageData.IsLink`/`ImageData.IsLinkOnly` distinguish an embedded picture from one that only references an external file path. `DocumentBuilder.InsertImage()` has overloads that accept an image, a file path, a byte array, or a stream, including variants that also set explicit width, height, horizontal and vertical position, and `WrapType` at insertion time. ### Fill, Stroke, and Shape Effects Every `Shape` and `GroupShape` carries a `Fill` object and a `Stroke` object for its interior and outline. `Fill` supports six fill kinds through `FillType`, with values including Solid, Patterned, Gradient, Textured, Background, and Picture, set with methods such as `Fill.Solid(color)`, `Fill.OneColorGradient(style, variant, degree)`, `Fill.TwoColorGradient(color1, color2, style, variant)`, `Fill.Patterned(patternType)`, or `Fill.SetImage(fileName)`. `Stroke` controls the outline: `Stroke.Weight`, `DashStyle`, `JoinStyle`, `EndCap`, and `Stroke.LineStyle` (a `ShapeLineStyle` value) cover the line itself, while `Stroke.StartArrowType` and `Stroke.EndArrowType`, paired with `ArrowWidth` and `ArrowLength` enums, configure arrowheads on connector and line shapes. Beyond fill and stroke, `Shape` exposes four further effect objects — `ShadowFormat`, `ReflectionFormat`, `GlowFormat`, and `SoftEdgeFormat` — each carrying its own color and transparency properties for the corresponding visual effect. ### Positioning and Text Wrapping Shapes that float relative to the page or paragraph use `RelativeHorizontalPosition` and `RelativeVerticalPosition` to anchor themselves — to the margin, page, or column, for example — paired with `RelativeHorizontalSize` and `RelativeVerticalSize` for size anchoring, plus `HorizontalAlignment` and `VerticalAlignment` for simple left/center/right or top/middle/bottom placement. How surrounding text reacts to a shape is controlled by `WrapType`, with values including Inline, Square, Tight, TopBottom, and None; for Square and Tight wrapping, `WrapSide` narrows it further to Left, Right, Both, or Largest. `FlipOrientation` mirrors a shape horizontally or vertically without changing its coordinates, and the `Shape.AllowOverlap`/`Shape.BehindText` flags control how a shape interacts with other floating content and the text layer beneath it. ### Signature Lines and Horizontal Rules Two more specialized shape kinds live in the same drawing model. `SignatureLine`, configured at insertion time through `SignatureLineOptions` (properties include `SignatureLineOptions.Signer`, `SignatureLineOptions.SignerTitle`, `SignatureLineOptions.Email`, `SignatureLineOptions.Instructions`, `SignatureLineOptions.ShowDate`, and `SignatureLineOptions.AllowComments`), renders the visual signature block seen in printable documents and exposes `SignatureLine.IsSigned` and `SignatureLine.IsValid` once a signature has been applied to it — this is distinct from the cryptographic digital-signature verification covered elsewhere, which works with signed document parts rather than the shape itself. `HorizontalRuleFormat` covers the plain divider line inserted with `DocumentBuilder.InsertHorizontalRule()`, with `HorizontalRuleFormat.WidthPercent`, `HorizontalRuleFormat.Height`, `HorizontalRuleFormat.NoShade`, `HorizontalRuleFormat.Color`, and `HorizontalRuleFormat.Alignment` properties (the last a `HorizontalRuleAlignment` value). --- ## Quick Start Aspose.Words FOSS for .NET is available via NuGet: To build from source instead: ```bash git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git cd Aspose.Words-FOSS-for-.NET dotnet build Aspose.Words.sln -c Release ``` Add a project reference to Aspose.Words.csproj from your application. From there, working with the drawing layer follows the pattern used throughout this post: load or create a `Document`, walk its shapes with `Document.GetChildNodes(NodeType.Shape, true)` or insert a new one with a `DocumentBuilder` method such as `DocumentBuilder.InsertImage()`, `DocumentBuilder.InsertGroupShape()`, or `DocumentBuilder.InsertHorizontalRule()`, then read or set properties on the returned `Shape` — `Shape.ImageData`, `Shape.TextBox`, `Shape.Fill`, `Shape.Stroke`, `Shape.WrapType`, and the rest — before calling `Document.Save()`. --- ## Supported Formats | Format | Extension | Read | Write | |--------|-----------|------|-------| | DOCX | .docx | ✓ | ✓ | | DOCM | .docm | ✓ | ✓ | | DOTX | .dotx | ✓ | ✓ | | DOTM | .dotm | ✓ | ✓ | | Flat OPC (all variants) | (various) | ✓ | ✓ | | Markdown | .md | ✓ | ✓ | | Text | .txt | ✓ | ✓ | This edition intentionally excludes page layout and rendering — no PDF, XPS, or image export, and no printing — so a shape's `Shape.Bounds` and layout-dependent geometry reflect the values stored in the document rather than a computed page layout. The additional format converters (DOC, RTF, ODT, HTML, EPUB, MHTML, MOBI, AZW3, and WordML) are not read or written; these are the same subsystems removed from the commercial codebase to keep this edition free. --- ## Open Source & Licensing Aspose.Words FOSS for .NET is released under the MIT license, free for both commercial and personal use with no royalties or redistribution restrictions. The full source is available on GitHub in the [Aspose.Words FOSS for .NET repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET). --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/net/getting-started/) - [Developer Guide](https://docs.aspose.org/words/net/developer-guide/) - [KB Articles](https://kb.aspose.org/words/net/) - [API Reference](https://reference.aspose.org/words/net/) - [GitHub Repository](https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/) --- # Aspose.Words FOSS for Python URL: https://blog.aspose.org/words/python/ --- Product: Aspose.Words Platform: python Page Type: index Canonical URL: https://blog.aspose.org/words/python/ --- # Aspose.Words FOSS for Python ## Related Resources - [Aspose.Words for Python — Enterprise Product](https://products.aspose.com/words/python/) ## Related Topics - [Introducing Aspose.Words FOSS for Python](https://blog.aspose.org/words/python/python-docx-word-converter/) - [Document Conversion with Aspose.Words FOSS for Python](https://blog.aspose.org/words/python/words-core-management-python/) --- # Introducing Aspose.Words FOSS for Python URL: https://blog.aspose.org/words/python/python-docx-word-converter/ Aspose.Words FOSS is a pure-Python library for loading, converting, and extracting text from Word documents. Supports DOCX, DOC, RTF, TXT, and Markdown input with PDF, Markdown, and plain-text output. MIT licensed. --- Product: Aspose.Words Platform: python Page Type: index Canonical URL: https://blog.aspose.org/words/python/python-docx-word-converter/ --- # Introducing Aspose.Words FOSS for Python ## Introduction Aspose.Words FOSS is an open-source Python library for working with Word documents. It reads DOCX, DOC, RTF, TXT, and Markdown files, and can export them to PDF, Markdown, or plain text — all without requiring Microsoft Word or any native dependencies. The library is released under the MIT License and is available on PyPI. Install it with: Aspose.Words FOSS requires Python 3.10 or later and depends on three pure-Python packages (`olefile`, `fpdf2`, `pydantic`), installed automatically by pip. --- ## Key Features ### Document Loading and Conversion The `Document` class is the primary entry point. Load a file in any supported input format, then use a dedicated Writer class (`LdmDocxWriter`, `LdmMarkdownWriter`, `LdmPdfWriter`) to convert it to a different output format. ```python import aspose.words_foss as aw from aspose.words_foss.md_writer import LdmMarkdownWriter doc = aw.Document("input.docx") # or .doc, .rtf, .txt, .md LdmMarkdownWriter().write(doc, "output.md") ``` ### PDF Export Export Word documents to PDF using `LdmPdfWriter`, passing a `PdfSaveOptions` instance for fine-grained control. ```python import aspose.words_foss as aw from aspose.words_foss.pdf_writer import LdmPdfWriter doc = aw.Document("input.docx") LdmPdfWriter().write(doc, "output.pdf") ``` ### Markdown Export with Save Options Pass a `MarkdownSaveOptions` or `PdfSaveOptions` instance to the writer's constructor for fine-grained control over output formatting. ```python import aspose.words_foss as aw from aspose.words_foss.md_writer import LdmMarkdownWriter from aspose.words_foss.pdf_writer import LdmPdfWriter from aspose.words_foss.saving import MarkdownSaveOptions, PdfSaveOptions doc = aw.Document("input.docx") md_opts = MarkdownSaveOptions() LdmMarkdownWriter(md_opts).write(doc, "output.md") pdf_opts = PdfSaveOptions() LdmPdfWriter(pdf_opts).write(doc, "output.pdf") ``` ### Text Extraction Extract plain text from any supported document format using the `Document.text` property. ```python import aspose.words_foss as aw doc = aw.Document("input.docx") text = doc.text ``` ### Document Structure Parsing Specialized parsers extract structured data from DOCX internals. `NumberingParser` reads list numbering definitions and `StyleParser` parses style names into structured objects. ### Multi-Format Input Support Load documents from five input formats — DOCX, DOC, RTF, TXT, and Markdown — using the same `Document` constructor. The `LoadFormat` enum provides constants for explicit format selection (`LoadFormat.DOCX`, `LoadFormat.DOC`, `LoadFormat.RTF`, `LoadFormat.TEXT`, `LoadFormat.MARKDOWN`). --- ## Quick Start Install the package and convert a DOCX file to all three output formats: ```python import aspose.words_foss as aw from aspose.words_foss.md_writer import LdmMarkdownWriter from aspose.words_foss.pdf_writer import LdmPdfWriter # Load a Word document doc = aw.Document("report.docx") # Export to Markdown LdmMarkdownWriter().write(doc, "report.md") # Export to PDF LdmPdfWriter().write(doc, "report.pdf") # Extract text directly and write it out as plain text text = doc.text with open("report.txt", "w", encoding="utf-8") as f: f.write(text) print(f"Extracted {len(text)} characters") ``` --- ## Supported Formats | Format | Extension | Read | Write | |----------|-------------|------|-------| | DOCX | .docx | ✓ | — | | DOC | .doc | ✓ | — | | RTF | .rtf | ✓ | — | | TXT | .txt | ✓ | — | | Markdown | .md | ✓ | ✓ | | PDF | .pdf | — | ✓ | --- ## Open Source & Licensing Aspose.Words FOSS for Python is released under the MIT License. You can use it freely in personal, internal, and commercial projects without license fees. The full source code is available on GitHub at the Aspose Words FOSS organization. --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/python/getting-started/) - [Developer Guide](https://docs.aspose.org/words/python/developer-guide/) - [KB Articles](https://kb.aspose.org/words/python/) - [API Reference](https://reference.aspose.org/words/python/) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/) - [Aspose.Words for Python — Enterprise Product](https://products.aspose.com/words/python-net/) --- # Document Conversion with Aspose.Words FOSS for Python URL: https://blog.aspose.org/words/python/words-core-management-python/ Learn how to convert Word documents from DOCX, DOC, RTF, and Markdown to PDF, Markdown, and plain text using Aspose.Words FOSS for Python. Covers the LdmPdfWriter/LdmMarkdownWriter classes and their save-options objects. --- Product: Aspose.Words Platform: python Page Type: index Canonical URL: https://blog.aspose.org/words/python/words-core-management-python/ --- # Document Conversion with Aspose.Words FOSS for Python ## Introduction Aspose.Words FOSS for Python provides a straightforward API for converting Word documents from supported input formats to PDF, Markdown, and plain text. The `Document` class loads files in five input formats and the `save()` method exports to PDF, Markdown, or plain text. This post walks through the core conversion workflows, from single-file conversion to batch processing across all supported formats. --- ## Key Features ### Single Document Conversion Load any supported input file and convert it to a target format with a Writer class. The `Document` constructor accepts DOCX, DOC, RTF, TXT, and Markdown files. ```python import aspose.words_foss as aw from aspose.words_foss.pdf_writer import LdmPdfWriter doc = aw.Document("input.docx") LdmPdfWriter().write(doc, "output.pdf") ``` ### Batch Conversion to Multiple Formats Reuse the same loaded document with multiple Writer classes to produce outputs in every supported format without reloading the input file. ```python import aspose.words_foss as aw from aspose.words_foss.md_writer import LdmMarkdownWriter from aspose.words_foss.pdf_writer import LdmPdfWriter doc = aw.Document("report.docx") LdmMarkdownWriter().write(doc, "report.md") LdmPdfWriter().write(doc, "report.pdf") with open("report.txt", "w", encoding="utf-8") as f: f.write(doc.text) ``` ### PDF Export with PdfSaveOptions Use `PdfSaveOptions` for fine-grained control over PDF output. For default settings, `LdmPdfWriter()` with no options is sufficient. ```python import aspose.words_foss as aw from aspose.words_foss.pdf_writer import LdmPdfWriter from aspose.words_foss.saving import PdfSaveOptions doc = aw.Document("input.docx") pdf_opts = PdfSaveOptions() LdmPdfWriter(pdf_opts).write(doc, "output.pdf") ``` ### Markdown Export with MarkdownSaveOptions Use `MarkdownSaveOptions` for additional control over Markdown output formatting. ```python import aspose.words_foss as aw from aspose.words_foss.md_writer import LdmMarkdownWriter from aspose.words_foss.saving import MarkdownSaveOptions doc = aw.Document("input.docx") md_opts = MarkdownSaveOptions() LdmMarkdownWriter(md_opts).write(doc, "output.md") ``` ### Text Extraction Extract plain text content from any loaded document using the `Document.text` property without writing to a file. ```python import aspose.words_foss as aw doc = aw.Document("input.docx") text = doc.text print(f"Extracted {len(text)} characters") ``` --- ## Quick Start ```python import aspose.words_foss as aw from aspose.words_foss.md_writer import LdmMarkdownWriter from aspose.words_foss.pdf_writer import LdmPdfWriter # Load a Word document doc = aw.Document("contract.docx") # Convert to all output formats LdmMarkdownWriter().write(doc, "contract.md") LdmPdfWriter().write(doc, "contract.pdf") with open("contract.txt", "w", encoding="utf-8") as f: f.write(doc.text) # Extract text for processing text = doc.text print(f"Document contains {len(text)} characters") ``` --- ## Supported Formats | Format | Extension | Read | Write | |----------|-----------|------|-------| | DOCX | .docx | ✓ | — | | DOC | .doc | ✓ | — | | RTF | .rtf | ✓ | — | | TXT | .txt | ✓ | — | | Markdown | .md | ✓ | ✓ | | PDF | .pdf | — | ✓ | --- ## Open Source & Licensing Aspose.Words FOSS for Python is released under the MIT License. You can use it in personal, internal, and commercial projects without license fees. The source code is available on GitHub. --- ## Getting Started - [Getting Started](https://docs.aspose.org/words/python/getting-started/) - [Developer Guide](https://docs.aspose.org/words/python/developer-guide/) - [KB Articles](https://kb.aspose.org/words/python/) - [API Reference](https://reference.aspose.org/words/python/) ## Related Resources - [Aspose.Words — Enterprise Blog](https://blog.aspose.com/)