officegen-dbb
Version:
Modification of Ziv Barber's officegen, to provide a reasonable way to have line breaks in table cells.
246 lines (206 loc) • 7.9 kB
JavaScript
//
// officegen: paragraph API for docx
//
// Please refer to README.md for this module's documentations.
//
// NOTE:
// - Before changing this code please refer to the hacking the code section on README.md.
//
// Copyright (c) 2013-2017 Ziv Barber;
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// 'Software'), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
var fast_image_size = require('fast-image-size');
/**
* This function implementing the paragraph API for docx based documents.
*
* @param {object} genobj The document object to work on it.
* @param {object} genPrivate Access to the internals of this object.
* @param {string} docType Must be the same as the new_type parameter to the document generator's constructor.
* @param {object} dataContainer Optional container to store the new object.
* @param {object} extraSettings Optional extra settings for the paragraph API itself.
* @param {object} options Paragraph options.
* @summary Implementation of the pptx document plugins system so it'll be easier to add new features.
* @constructor
* @name MakeDocxP
*/
function MakeDocxP ( genobj, genPrivate, docType, dataContainer, extraSettings, options ) {
// Save everything because we'll need it later:
this.docType = docType;
this.genPrivate = genPrivate;
this.ogPluginsApi = genPrivate.plugs; // Generic officegen API for plugins.
this.msPluginsApi = genPrivate.plugs.type.msoffice; // msoffice plugins API.
this.genobj = genobj;
this.data = [];
this.extraSettings = extraSettings || {};
this.options = options || {};
this.mainPath = genPrivate.features.type.msoffice.main_path; // The "folder" name inside the document zip that all the specific resources of this document type are stored.
this.mainPathFile = genPrivate.features.type.msoffice.main_path_file; // The name of the main real xml resource of this document.
this.relsMain = genPrivate.type.msoffice.rels_main; // Main rels file.
this.relsApp = genPrivate.type.msoffice.rels_app; // Main rels file inside the specific document type "folder".
this.filesList = genPrivate.type.msoffice.files_list; // Resources list xml.
this.srcFilesList = genPrivate.type.msoffice.src_files_list; // For storing extra files inside the document zip.
if ( dataContainer ) {
dataContainer.push ( this );
} // Endif.
return this;
}
/**
* Insert text inside this paragraph.
*
* @param {string} text_msg The text message itself.
* @param {object} opt ???.
* @param {object} flag_data ???.
*/
MakeDocxP.prototype.addText = function ( text_msg, opt, flag_data ) {
var newP = this;
var objNum = newP.data.length
newP.data[objNum] = { text: text_msg, options: opt || {}, ext_data: flag_data };
if ((opt || {}).link) {
var link_rel_id = newP.relsApp.length + 1;
newP.relsApp.push({
type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
target: opt.link,
targetMode: 'External'
})
newP.data[objNum].link_rel_id = link_rel_id;
}
};
/**
* Insert a line break inside this paragraph.
*/
MakeDocxP.prototype.addLineBreak = function () {
var newP = this;
newP.data[newP.data.length] = { 'line_break': true };
};
/**
* Insert a horizontal line inside this paragraph.
*/
MakeDocxP.prototype.addHorizontalLine = function () {
var newP = this;
newP.data[newP.data.length] = { 'horizontal_line': true };
};
/**
* Insert a bookmark here.
* @param {string} anchorName The anchor of this bookmark.
*/
MakeDocxP.prototype.startBookmark = function ( anchorName ) {
var newP = this;
newP.data[newP.data.length] = { 'bookmark_start': anchorName };
};
/**
* Close the previous placed bookmark.
*/
MakeDocxP.prototype.endBookmark = function () {
var newP = this;
newP.data[newP.data.length] = { 'bookmark_end': true };
};
/**
* Insert an image into the current paragraph.
*
* @param {object} image_path The image file to add.
* @param {object} opt Additional options (cx, cy).
* @param {object} image_format_type ???.
*/
MakeDocxP.prototype.addImage = function ( image_path, opt, image_format_type ) {
var newP = this;
var image_type = (typeof image_format_type == 'string') ? image_format_type : 'png';
var defWidth = 320;
var defHeight = 200;
if ( typeof image_path == 'string' ) {
var ret_data = fast_image_size ( image_path );
if ( ret_data.type == 'unknown' ) {
var image_ext = path.extname ( image_path );
switch ( image_ext ) {
case '.bmp':
image_type = 'bmp';
break;
case '.gif':
image_type = 'gif';
break;
case '.jpg':
case '.jpeg':
image_type = 'jpeg';
break;
case '.emf':
image_type = 'emf';
break;
case '.tiff':
image_type = 'tiff';
break;
} // End of switch.
} else {
if ( ret_data.width ) {
defWidth = ret_data.width;
} // Endif.
if ( ret_data.height ) {
defHeight = ret_data.height;
} // Endif.
image_type = ret_data.type;
if ( image_type == 'jpg' ) {
image_type = 'jpeg';
} // Endif.
} // Endif.
} // Endif.
var objNum = newP.data.length;
newP.data[objNum] = { image: image_path, options: opt || {} };
if ( !newP.data[objNum].options.cx && defWidth ) {
newP.data[objNum].options.cx = defWidth;
} // Endif.
if ( !newP.data[objNum].options.cy && defHeight ) {
newP.data[objNum].options.cy = defHeight;
} // Endif.
var image_id = newP.srcFilesList.indexOf ( image_path );
var image_rel_id = -1;
if ( image_id >= 0 ) {
for ( var j = 0, total_size_j = newP.relsApp.length; j < total_size_j; j++ ) {
if ( newP.relsApp[j].target == ('media/image' + (image_id + 1) + '.' + image_type) ) {
image_rel_id = j + 1;
} // Endif.
} // Endif.
} else
{
image_id = newP.srcFilesList.length;
newP.srcFilesList[image_id] = image_path;
newP.ogPluginsApi.intAddAnyResourceToParse ( newP.mainPath + '\\media\\image' + (image_id + 1) + '.' + image_type, (typeof image_path == 'string') ? 'file' : 'stream', image_path, null, false );
} // Endif.
if ( image_rel_id == -1 ) {
image_rel_id = newP.relsApp.length + 1;
newP.relsApp.push (
{
type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
target: 'media/image' + (image_id + 1) + '.' + image_type,
clear: 'data'
}
);
} // Endif.
if ((opt || {}).link) {
var link_rel_id = newP.relsApp.length + 1;
newP.relsApp.push({
type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
target: opt.link,
targetMode: 'External'
});
newP.data[objNum].link_rel_id = link_rel_id;
} // Endif.
newP.data[objNum].image_id = image_id;
newP.data[objNum].rel_id = image_rel_id;
};
module.exports = MakeDocxP;