Skip to content

Commit

Permalink
Merge pull request #5 from UniversityOfNicosia/feature/document-forma…
Browse files Browse the repository at this point in the history
…tting-enhancements

Enhance Document Conversion API with Table and Code Block Support
  • Loading branch information
HlexNC committed Apr 10, 2024
2 parents 3c616e4 + 10dd574 commit 6bd4e6a
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,5 @@ dist
__pycache__/

# Ingone generaed files
converted_files/
converted_files/
*.docx
93 changes: 93 additions & 0 deletions officegen-api/examples/api-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,99 @@ Content-Type: application/json
}
```

<details>
<summary>Advanced example</summary>

```json
{
"elements": [
{
"type": "title",
"text": "Document Title"
},
{
"type": "subtitle",
"text": "Document Subtitle"
},
{
"type": "paragraph",
"text": "This is a simple paragraph."
},
{
"type": "bullet",
"items": [
"Item 1",
"Item 2",
"Item 3"
]
},
{
"type": "list",
"items": [
"Item 1",
"Item 2",
"Item 3"
]
},
{
"type": "footnotes",
"text": "This is document footnotes"
},
{
"type": "codeBlock",
"text": "function helloWorld() {\n console.log('Hello, world!');\n}"
},
{
"type": "table",
"table": [
[
{
"val": "Header 1",
"opts": {
"b": true,
"color": "000000",
"align": "center",
"shd": {
"fill": "92CDDC"
}
}
},
{
"val": "Header 2",
"opts": {
"b": true,
"color": "000000",
"align": "center",
"shd": {
"fill": "92CDDC"
}
}
}
],
["Row 1, Cell 1", "Row 1, Cell 2"],
["Row 2, Cell 1", "Row 2, Cell 2"]
],
"tableStyle": {
"tableColWidth": 4261,
"tableSize": 24,
"tableColor": "ada",
"tableAlign": "left",
"tableFontFamily": "Comic Sans MS"
}
}
],
"styles": {
"textColor": "#000000",
"fontFamily": {
"title": "Arial",
"subtitle": "Times New Roman",
"body": "Calibri"
}
}
}
```
</details>

### Response

Upon successful document creation, the API will respond with a 201 status code and a JSON object containing the message and the path to the created document.
Expand Down
4 changes: 2 additions & 2 deletions officegen-api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion officegen-api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@universityofnicosia/unic-document-conversion-library",
"version": "1.0.6",
"version": "1.1.0",
"description": "A library and API for document conversion using officegen",
"main": "src/documentLibrary.js",
"scripts": {
Expand Down
27 changes: 22 additions & 5 deletions officegen-api/src/utils/officegenHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ const fs = require('fs');
const path = require('path');

// Function to apply elements and styles to a DOCX document
function applyElementsAndStyles(docx, elements, styles) {
function applyElementsAndStyles(docx, elements, styles = {}) {
elements.forEach(element => {
let options = {
color: styles.textColor || '#000000',
font_face: styles.fontFamily.body || 'Calibri',
font_face: styles.fontFamily?.body || 'Calibri',
font_size: 12
};

Expand Down Expand Up @@ -49,8 +49,26 @@ function applyElementsAndStyles(docx, elements, styles) {
let footnote = docx.createP();
footnote.addText(element.text, { ...options, italic: true});
break;
case 'codeBlock':
let codeBlock = docx.createP();
codeBlock.addText(element.text, { font_face: 'Courier New', font_size: 10 });
break;
case 'table':
docx.createTable(element.table, element.tableStyle);
break;
case 'image':
let imageParagraph = docx.createP();
imageParagraph.addImage(path.resolve(__dirname, element.path), element.options);
break;
case 'pageBreak':
docx.putPageBreak();
break;
case 'horizontalLine':
let lineParagraph = docx.createP();
lineParagraph.addHorizontalLine();
break;
default:
console.log(`Unsupported element type: ${element.type}`);
console.warn(`Unsupported element type: ${element.type}`);
let unsupported = docx.createP();
unsupported.addText(element.text, options);
break;
Expand All @@ -68,8 +86,7 @@ exports.createDocxWithStructure = async (elements, styles, outputPath = 'documen
applyElementsAndStyles(docx, elements, styles);

// Define the output stream
const out = fs.createWriteStream(path.join(__dirname, '..', '..', 'examples', outputPath));

const out = fs.createWriteStream(outputPath);
out.on('error', (err) => {
console.error('File stream error:', err);
reject(err);
Expand Down
94 changes: 94 additions & 0 deletions officegen-api/tests/documentService.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const { createDocumentWithStructure, createDocumentBuffer } = require("../src/documentLibrary");
const { createDocxWithStructure } = require("../src/utils/officegenHelper");

// Directory for test outputs
const outDir = path.join(__dirname, "../tests_output/");

// Ensure the output directory exists before running tests
beforeAll(() => {
if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir, { recursive: true });
}
});

// Main test suite for document conversion functionalities
describe("Document Conversion API Tests", () => {

// Test for creating a document with mixed content types
it("should create a document with titles, text, and code blocks", async () => {
const elements = [
{ type: "title", text: "Document Title" },
{ type: "subtitle", text: "Subtitle here" },
{ type: "text", text: "Some basic text" },
{ type: "codeBlock", text: 'console.log("Hello, world!");' },
];
const styles = {
textColor: "#000000",
fontFamily: {
body: "Calibri",
title: "Arial",
subtitle: "Times New Roman",
},
};
const outputPath = path.join(outDir, "testDocument.docx");

await createDocxWithStructure(elements, styles, outputPath);

// Verify document creation
assert(fs.existsSync(outputPath), "Document should be successfully created");
});

// Test for generating a document buffer
it("should generate a buffer for a document with paragraph content", async () => {
const elements = [{ type: "paragraph", text: "Paragraph within a buffer" }];
const buffer = await createDocumentBuffer(elements, {});

// Buffer validations
assert(buffer instanceof Buffer, "Should return a valid buffer");
assert(buffer.length > 0, "Generated buffer should not be empty");
});

// Test for creating a document with a table
it("should create a document with a table", async () => {
const elements = [
{ type: "title", text: "Document with Table" },
{
type: "table",
table: [
// Table header
[
{ val: "Header 1", opts: { b: true, sz: "24", shd: { fill: "cccccc" } }},
{ val: "Header 2", opts: { b: true, sz: "24", shd: { fill: "cccccc" } }},
],
// Table rows
["Row 1, Cell 1", "Row 1, Cell 2"],
["Row 2, Cell 1", "Row 2, Cell 2"],
],
tableStyle: {
tableColWidth: 4261,
tableSize: 24,
tableColor: "ada",
tableAlign: "left",
tableFontFamily: "Comic Sans MS",
},
},
];
const styles = {
textColor: "#000000",
fontFamily: {
body: "Calibri",
title: "Arial",
},
};
const outputPath = path.join(outDir, "testDocumentWithTable.docx");

await createDocxWithStructure(elements, styles, outputPath);

// Verify table document creation
assert(fs.existsSync(outputPath), "Document with a table should be successfully created");
});

});

0 comments on commit 6bd4e6a

Please sign in to comment.