OpenXML Excel C# Update Stylesheet and add new Style to existing Stylesheet - openxml

I need to add another style to an existing stylesheet. I created this style using the OpenXML Productivity Tools. Unfortunately I can't manage to add this style to the existing stylesheet. The stylesheet is always overwritten. Do I need to adjust the counts (borders, fills, etc)? Or is there a better way?
void AppendStylesToStylesheet(WorkbookStylesPart workbookStylesPart)
{
var styleSheet = workbookStylesPart.Stylesheet;
var fonts1 = new Fonts { Count = 1U, KnownFonts = true };
var font1 = new Font();
font1.Append(new FontSize { Val = 11D });
font1.Append(new Color { Theme = 1U });
font1.Append(new FontName { Val = "Calibri" });
font1.Append(new FontFamilyNumbering { Val = 2 });
font1.Append(new FontScheme { Val = FontSchemeValues.Minor });
fonts1.Append(font1);
var fills1 = new Fills { Count = 3U };
var fill1 = new Fill();
fill1.Append(new PatternFill { PatternType = PatternValues.None });
var fill2 = new Fill();
fill2.Append(new PatternFill { PatternType = PatternValues.Gray125 });
var fill3 = new Fill();
var patternFill3 = new PatternFill { PatternType = PatternValues.Solid };
patternFill3.Append(new ForegroundColor { Theme = 0U, Tint = -4.9989318521683403E-2D });
patternFill3.Append(new BackgroundColor { Indexed = 64U });
fill3.Append(patternFill3);
fills1.Append(fill1);
fills1.Append(fill2);
fills1.Append(fill3);
var borders1 = new Borders { Count = 2U };
var border1 = new Border();
var leftBorder1 = new LeftBorder();
var rightBorder1 = new RightBorder();
var topBorder1 = new TopBorder();
var bottomBorder1 = new BottomBorder();
var diagonalBorder1 = new DiagonalBorder();
border1.Append(leftBorder1);
border1.Append(rightBorder1);
border1.Append(topBorder1);
border1.Append(bottomBorder1);
border1.Append(diagonalBorder1);
var border2 = new Border();
var leftBorder2 = new LeftBorder();
var rightBorder2 = new RightBorder();
var topBorder2 = new TopBorder { Style = BorderStyleValues.Dotted };
topBorder2.Append(new Color { Theme = 0U, Tint = -0.24994659260841701D });
var bottomBorder2 = new BottomBorder { Style = BorderStyleValues.Dotted };
bottomBorder2.Append(new Color { Theme = 0U, Tint = -0.24994659260841701D });
var diagonalBorder2 = new DiagonalBorder();
border2.Append(leftBorder2);
border2.Append(rightBorder2);
border2.Append(topBorder2);
border2.Append(bottomBorder2);
border2.Append(diagonalBorder2);
borders1.Append(border1);
borders1.Append(border2);
var cellStyleFormats1 = new CellStyleFormats { Count = 1U };
cellStyleFormats1.Append(new CellFormat { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U });
var cellFormats1 = new CellFormats { Count = 3U };
var cellFormat2 = new CellFormat { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U, FormatId = 0U };
var cellFormat3 = new CellFormat { NumberFormatId = 14U, FontId = 0U, FillId = 2U, BorderId = 1U, FormatId = 0U, ApplyNumberFormat = true, ApplyFill = true, ApplyBorder = true, ApplyAlignment = true };
var alignment1 = new Alignment { Vertical = VerticalAlignmentValues.Center };
cellFormat3.Append(alignment1);
var cellFormat4 = new CellFormat { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U, FormatId = 0U, ApplyAlignment = true };
var alignment2 = new Alignment { Vertical = VerticalAlignmentValues.Center };
cellFormat4.Append(alignment2);
cellFormats1.Append(cellFormat2);
cellFormats1.Append(cellFormat3);
cellFormats1.Append(cellFormat4);
var cellStyles1 = new CellStyles { Count = 1U };
var cellStyle1 = new CellStyle { Name = "Standard", FormatId = 0U, BuiltinId = 0U };
cellStyles1.Append(cellStyle1);
var differentialFormats1 = new DifferentialFormats { Count = 0U };
var tableStyles1 = new TableStyles { Count = 0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleLight16" };
var colors1 = new Colors();
var mruColors1 = new MruColors();
var color4 = new Color { Rgb = "FFFFFFCC" };
mruColors1.Append(color4);
colors1.Append(mruColors1);
var stylesheetExtensionList1 = new StylesheetExtensionList();
var stylesheetExtension1 = new StylesheetExtension { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" };
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
var slicerStyles1 = new X14.SlicerStyles { DefaultSlicerStyle = "SlicerStyleLight1" };
stylesheetExtension1.Append(slicerStyles1);
var stylesheetExtension2 = new StylesheetExtension { Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}" };
stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
var timelineStyles1 = new X15.TimelineStyles { DefaultTimelineStyle = "TimeSlicerStyleLight1" };
stylesheetExtension2.Append(timelineStyles1);
stylesheetExtensionList1.Append(stylesheetExtension1);
stylesheetExtensionList1.Append(stylesheetExtension2);
styleSheet.Append(fonts1);
styleSheet.Append(fills1);
styleSheet.Append(borders1);
styleSheet.Append(cellStyleFormats1);
styleSheet.Append(cellFormats1);
styleSheet.Append(cellStyles1);
styleSheet.Append(differentialFormats1);
styleSheet.Append(tableStyles1);
styleSheet.Append(colors1);
styleSheet.Append(stylesheetExtensionList1);
styleSheet.Save();
}

Related

How can embed a excel file to PowerPoint file by OpenXML?

I want embed a excel file to powerpoint file:
I had try this code, but it can't add object:
// Open the source document as read/write.
using (var presentationDocument = PresentationDocument.Open(strFile, true))
{
var presentationPart = presentationDocument.PresentationPart;
var newSlidePart = GetSlidePartsInOrder( presentationPart).Last();
string datafile = #"F:\AUTOM\t1.xlsx";
ShapeTree tree = newSlidePart.Slide.CommonSlideDatShapeTree;
GraphicFrame graphicFrame = new GraphicFrame();
var embedId = "rId" + (newSlidePart.Slide.Elements().Count() + 1915);
var nonVisualPictureProperties = new NonVisualGraphicFrameProperties(
new NonVisualDrawingProperties { Id = (UInt32Value)4U, Name = "Chart 3" },
new NonVisualGraphicFrameDrawingProperties(),
new ApplicationNonVisualDrawingProperties());
var blipFill = new BlipFill();
var blip = new Blip { Embed = embedId };
// Creates an BlipExtensionList instance and adds its children
var blipExtensionList = new BlipExtensionList();
var blipExtension = new BlipExtension { Uri = "{28A0092B-C50C-407E-A947-70E740481C1D}" };
var useLocalDpi = new UseLocalDpi { Val = false };
useLocalDpi.AddNamespaceDeclaration("a14", "http://schemas.microsoft.com/office/drawing/2010/main");
blipExtension.Append(useLocalDpi);
blipExtensionList.Append(blipExtension);
bliAppend(blipExtensionList);
var stretch = new Stretch();
var fillRectangle = new FillRectangle();
stretch.Append(fillRectangle);
blipFill.Append(blip);
blipFill.Append(stretch);
// Create new Embedded Package Part
EmbeddedPackagePart embPackage = newSlidePart.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", embedId);
// Feed imported data from an excel file into the embedded package
embPackage.FeedData(new FileStream(datafile, FileMode.Open, FileAccess.ReadWrite));
var aspectRatio = 1;
// Compute the image's offset on the page (in x and y), and its width cx and height cy.
// Note that sizes are expressed in EMU (English Metric Units)
// const int emusPerCm = 360000;
var cy = 5029200L;
var cx = (long)(cy * aspectRatio);
if (cx > 8229600L)
{
cx = 8229600L;
cy = (long)(cx / aspectRatio);
}
// Creates an ShapeProperties instance and adds its children.
var shapeProperties = new ShapeProperties();
var transform2D = new Transform2D();
var offset = new Offset { X = (9144000L - cx) / 2, Y = 1524000L };
var extents = new Extents { Cx = cx, Cy = cy };
transform2D.Append(offset);
transform2D.Append(extents);
var presetGeometry = new PresetGeometry { Preset = ShapeTypeValues.Rectangle };
var adjustValueList = new AdjustValueList();
presetGeometry.Append(adjustValueList);
shapeProperties.Append(transform2D);
shapeProperties.Append(presetGeometry);
graphicFrame.Append(nonVisualPictureProperties);
graphicFrame.Append(blipFill);
graphicFrame.Append(shapeProperties);
tree.AppendChild(graphicFrame);
// Save the modified presentation.
presentationPart.Presentation.Save();
}
How can embed a excel file to PowerPoint file by OpenXML?

How to generate leaflet control from database

I wish to generate a custom dropdown filter, based on categories from a database.
How is this achieved?
In my example, this is (poorly) implemented with some hard coding and duplication.
var serviceOverlays = [
{name:"Cardiology", value:"cardiology"},
{name:"Opthamology", value:"opthamology"}
];
var oSelect = L.control({position : 'topright'});
oSelect.onAdd = function (map) {
var overlayParent = document.getElementById('new-parent'); // overlays div
var node = L.DomUtil.create('select', 'leaflet-control');
node.innerHTML = '<option value="cardiologist">Cardioligist</option><option value="opthamology">Opthamology</option>';
overlayParent.appendChild(node);
L.DomEvent.disableClickPropagation(node);
L.DomEvent.on(node,'change',function(e){
var select = e.target;
for(var name in serviceOverlays){
serviceOverlays[name].removeFrom(map);
}
serviceOverlays[select.value].addTo(map);
});
Fiddle
I created a Control for you:
L.Control.Select = L.Control.extend({
options: {
position : 'topright'
},
initialize(layers,options) {
L.setOptions(this,options);
this.layers = layers;
},
onAdd(map) {
this.overlayParent = L.DomUtil.create('div', 'leaflet-control select-control');
this.node = L.DomUtil.create('select', 'leaflet-control',this.overlayParent);
L.DomEvent.disableClickPropagation(this.node);
this.updateSelectOptions();
L.DomEvent.on(this.node,'change',(e)=>{
var select = e.target;
for(var value in this.layers){
this.layers[value].layer.removeFrom(map);
}
this.layers[select.value].layer.addTo(map);
});
return this.overlayParent;
},
updateSelectOptions(){
var options = "";
if(this.layers){
for(var value in this.layers){
var layer = this.layers[value];
options += '<option value="'+value+'">'+layer.name+'</option>';
}
}
this.node.innerHTML = options;
},
changeLayerData(layers){
this.layers = layers;
this.updateSelectOptions();
}
});
var oSelect = new L.Control.Select(serviceOverlays,{position : 'topright'}).addTo(map);
The data structure have to be:
var serviceOverlays = {
"cardiology": {name:"Cardiology", layer: cities},
"opthamology": {name:"Opthamology", layer: badCities}
};
Demo: https://jsfiddle.net/falkedesign/1rLntbo5/
You can also change the data dynamicl< with oSelect.changeLayerData(serviceOverlays2)

File Uploader - Upload excel file and convert it into JSON and bind to the table

After uploading the excel file on file uploader control in sapui5, excel file is converted in to JSON using following code.
handleExcelUpload : function(e) {
this._import(e.getParameter("files")
&& e.getParameter("files")[0]);
},
_import : function(file) {
if (file && window.FileReader) {
var reader = new FileReader();
that = this;
result = {};
var data;
reader.onload = function(e) {
var data = e.target.result;
var wb = XLSX.read(data, {
type : 'binary'
});
wb.SheetNames
.forEach(function(sheetName) {
var roa = XLSX.utils
.sheet_to_row_object_array(wb.Sheets[sheetName]);
if (roa.length > 0) {
result[sheetName] = roa;
}
});
};
reader.readAsBinaryString(file);
};
},
Note : I have used jszip.js and xlsx.js library to convert excel to JSON
Now in result variable I am getting JSON format data, and this data I have bind to the table.
The issue is, JSON binding with table is working fine with the Chrome, Firefox latest browser but, its not working on in IE 11 browser or it's showing only No data in table
Is there any other file reader method which supports IE11?
Yes I got answer.. I found readAsArrayBuffer method in Javascript which is compatible for all latest browser even in IE11
Here is my working code.
XML code:
<FileUploader id="fileUploader" name="myFileUpload"
class="sapUiSmallMarginEnd" uploadUrl="upload/" width="400px"
tooltip="Upload your file to the local server" uploadComplete="handleUploadComplete"
change="handleExcelUpload" placeholder="Please Select File" />
JS code:
handleExcelUpload : function(e) {
this._import(e.getParameter("files")
&& e.getParameter("files")[0]);
},
_import : function(file) {
debugger;
if (file && window.FileReader) {
var reader = new FileReader();
that = this;
//result = {};
//var data;
reader.onload = function(evt) {
var data = evt.target.result;
//var xlsx = XLSX.read(data, {type: 'binary'});
var arr = String.fromCharCode.apply(null, new Uint8Array(data));
var xlsx = XLSX.read(btoa(arr), {type: 'base64'});
result = xlsx.Strings;
result = {};
xlsx.SheetNames.forEach(function(sheetName) {
var rObjArr = XLSX.utils.sheet_to_row_object_array(xlsx.Sheets[sheetName]);
if(rObjArr.length > 0){
result[sheetName] = rObjArr;
}
});
return result;
that.b64toBlob(xlsx, "binary");
};
reader.readAsArrayBuffer(file);
};
},
b64toBlob : function(b64Data, contentType) {
contentType = contentType || '';
var sliceSize = 512;
b64Data = b64Data.replace(/^[^,]+,/, '');
b64Data = b64Data.replace(/\s/g, '');
var byteCharacters = Base64.decode(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length;offset += sliceSize){
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {
type : contentType
});
}
After this add the base64 util
var Base64 = {}; // Base64 namespace
Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
Base64.encode = function(str, utf8encode) {
utf8encode = (typeof utf8encode == 'undefined') ? false : utf8encode;
var o1, o2, o3, bits, h1, h2, h3, h4, e=[], pad = '', c, plain, coded;
var b64 = Base64.code;
plain = utf8encode ? Utf8.encode(str) : str;
c = plain.length % 3;
if (c > 0) { while (c++ < 3) { pad += '='; plain += '\0'; } }
for (c=0; c<plain.length; c+=3) {
o1 = plain.charCodeAt(c);
o2 = plain.charCodeAt(c+1);
o3 = plain.charCodeAt(c+2);
bits = o1<<16 | o2<<8 | o3;
h1 = bits>>18 & 0x3f;
h2 = bits>>12 & 0x3f;
h3 = bits>>6 & 0x3f;
h4 = bits & 0x3f;
e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
}
coded = e.join('');
coded = coded.slice(0, coded.length-pad.length) + pad;
return coded;
}
Base64.decode = function(str, utf8decode) {
utf8decode = (typeof utf8decode == 'undefined') ? false : utf8decode;
var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded;
var b64 = Base64.code;
coded = utf8decode ? Utf8.decode(str) : str;
for (var c=0; c<coded.length; c+=4) {
h1 = b64.indexOf(coded.charAt(c));
h2 = b64.indexOf(coded.charAt(c+1));
h3 = b64.indexOf(coded.charAt(c+2));
h4 = b64.indexOf(coded.charAt(c+3));
bits = h1<<18 | h2<<12 | h3<<6 | h4;
o1 = bits>>>16 & 0xff;
o2 = bits>>>8 & 0xff;
o3 = bits & 0xff;
d[c/4] = String.fromCharCode(o1, o2, o3);
// check for padding
if (h4 == 0x40) d[c/4] = String.fromCharCode(o1, o2);
if (h3 == 0x40) d[c/4] = String.fromCharCode(o1);
}
plain = d.join(''); // join() is far faster than repeated string concatenation in IE
return utf8decode ? Utf8.decode(plain) : plain;
}
Try this, without external library:
/*In the function "Press" */
var file = oFileUploader.getFocusDomRef().files[0];
if (file && window.FileReader) {
var reader = new FileReader();
var that = this;
reader.onload = function(e) {
var strCSV = e.target.result;
var arrCSV = strCSV.replace(/['",]/g, '').split(/[↵\n]+/).join(';').split(';');
var noOfCols = 11; // 11 Columns
var hdrRow = arrCSV.splice(0, noOfCols);
var oData = [];
while (arrCSV.length > 0) {
var obj = {};
var row = arrCSV.splice(0, noOfCols)
if (row.length > 1) {
for (var i = 0; i < row.length; i++) obj[hdrRow[i].replace(/\r/g, "")] = row[i].trim();
oData.push(obj) // Data Json
}
}
oTable.setModel(new sap.ui.model.json.JSONModel(oData)); // Binding model
};
reader.readAsText(file, 'ISO-8859-1');
}
Regards.
Check the code in my gist
Upload_CSV.js
Place this in the controller to parse the file using JS client side
var fU = this.getView().byId("idfileUploader");
var domRef = fU.getFocusDomRef();
var file = domRef.files[0];
var reader = new FileReader();
var params = "ItemsJson=";
reader.onload = function(oEvent) {
var strCSV = oEvent.target.result;
var arrCSV = strCSV.match(/[\w .]+(?=,?)/g);
var noOfCols = 3;
var headerRow = arrCSV.splice(0, noOfCols);
var data = [];
while (arrCSV.length > 0) {
var obj = {};
var row = arrCSV.splice(0, noOfCols);
for (var i = 0; i < row.length; i++) {
obj[headerRow[i]] = row[i].trim();
}
data.push(obj);
}
data.reverse();
var json = JSON.stringify(data); // send to the backend
if I did not answer you please tell me

leaflet marker dragging moves map

I am working on OSM using leaflet..I enable dragging:true on my destination marker as I need it to be draggable ,but while dragging marker my MAP also moves .Is there a way I can only move the marker.
$(document).ready(function()
{
homepg();
});
var cab_map = null;
function homepg()
{
var str = '';
var markers = new L.MarkerClusterGroup();
var lat = '19.068246';
var lng = '72.850638';
cab_map = ddmap.init('mapdivcab',[lat,lng],14);
ddmap.getDirection(13.039680,77.580214,13.040850,77.625532,cab_map,'lmenu');
}
getDirection: function(flat,flon,tlat,tlon,map,mapdv)
{
this.dirMap = map;
this.mapDiv = mapdv;
this.sourceLatLng = new L.LatLng(flat,flon);
this.targetLatLng = new L.LatLng(tlat,tlon);
if(this.fScript)
head.removeChild(fScript);
fScript = document.createElement('script');
fScript.setAttribute("type","text/javascript");
fScript.setAttribute("src", ddmap.serverUrl+"jsonp=ddmap.updateAddressFrom/nearbylocation/"+flat.toFixed(6).replace('.','')+"/"+flon.toFixed(6).replace('.','')+"/1?json_callback=%jsonp");
document.getElementsByTagName("head")[0].appendChild(fScript);
if(this.tScript)
head.removeChild(tScript);
tScript = document.createElement('script');
tScript.setAttribute("type","text/javascript");
tScript.setAttribute("src", ddmap.serverUrl+"jsonp=ddmap.updateAddressTo/nearbylocation/"+tlat.toFixed(6).replace('.','')+"/"+tlon.toFixed(6).replace('.','')+"/1?json_callback=%jsonp");
document.getElementsByTagName("head")[0].appendChild(tScript);
if(this.currentScript)
head.removeChild(currentScript);
currentScript = document.createElement('script');
currentScript.setAttribute("type","text/javascript");
currentScript.setAttribute("src", "viaroute?z=13&output=json&jsonp=ddmap.showRoute&loc="+flat+","+flon+"&loc="+tlat+","+tlon+"&instructions=true");
document.getElementsByTagName("head")[0].appendChild(currentScript);
}
showRoute: function(response) {
var geometry = this._decode(response.route_geometry, 6);
var route = new L.Polyline( [], {dashArray:""} );
route.setLatLngs( geometry );
var sIcon = L.icon({iconUrl:this.imageHost+"/images/marker-source.png",iconAnchor:[10,30],shadowUrl: this.imageHost+'/images/marker-shadow.png'});
var tIcon = L.icon({iconUrl:this.imageHost+"/images/marker-target.png",iconAnchor:[10,30],shadowUrl: this.imageHost+'/images/marker-shadow.png'});
mrkrSrc = L.marker(this.sourceLatLng, {icon: sIcon});
mrkrTgt = L.marker(this.targetLatLng, {icon: tIcon,draggable:'true'});
if(this.mainLayer)
this.dirMap.removeLayer(this.mainLayer);
this.mainLayer = L.layerGroup([mrkrSrc, mrkrTgt])
.addLayer(route)
.addTo(this.dirMap);
var bounds = new L.LatLngBounds(this.sourceLatLng, this.targetLatLng);
this.dirMap.fitBounds(bounds);
this.showRouteDesc(response,geometry);
//
mrkrTgt.on('drag', function(event){
var marker = event.target;
var dst = marker.getLatLng();
var src = mrkrSrc.getLatLng();
ddmap.getroute(src.lat,src.lng,dst.lat,dst.lng,cab_map,'lmenu');//instead of calling getDriection i m calling this function
});
//this function is same as getDirection but i have removed some code, thought that is not required and it was making 'drag event' rough and time taking
getroute: function(flat,flon,tlat,tlon,map,mapdv)
{
this.dirMap = map;
this.mapDiv = mapdv;
this.sourceLatLng = new L.LatLng(flat,flon);
this.targetLatLng = new L.LatLng(tlat,tlon);
if(this.currentScript)
head.removeChild(currentScript);
currentScript = document.createElement('script');
currentScript.setAttribute("type","text/javascript");
currentScript.setAttribute("src", "viaroute?z=13&output=json&jsonp=ddmap.showRoute&loc="+flat+","+flon+"&loc="+tlat+","+tlon+"&instructions=true");
document.getElementsByTagName("head")[0].appendChild(currentScript);
}

TinyMCE strip_tags function like php?

how can I accept just certain tags and strip_tags all others when paste text to editor? just like php's strip_tags function?
and how can I remove all styles from that tags?
input is a string.
i have a function to this
var strip_tags = function(str,tags,attrs){
var reg2 = /\s*(\w+)=\"[^\"]+\"/gm;
var reg = /<\s*(\w+).*?>/gm;
str = str.replace(reg,function(match, i) {
var r_ = match;
var reg_ = /<\s*(\w+).*?>/gm;
var m_ = reg_.exec(match);
if(m_!=null){
if(tags.indexOf(m_[1])>=0){
r_ = match.replace(reg2,function(match_, i) {
var reg2_ = /\s*(\w+)=\"[^\"]+\"/gm;
var m = reg2_.exec(match_);
if(m!=null){
if(attrs.indexOf(m[1])>=0){
return match_;
}
}
return '';
});
}else{
r_ = '';
}
}else{
r_ = '';
}
return r_;
});
var reg3 = /<\/\s*(\w+).*?>/gm;
str = str.replace(reg3,function(match, i) {
var r_ = match;
var reg_ = /<\/\s*(\w+).*?>/gm;
var m_ = reg_.exec(match);
if(m_!=null){
if(tags.indexOf(m_[1])>=0){
return match;
}
}
return '';
});
return str;
};
tinyMCE.init(
...
plugins: "paste...
paste_preprocess : function(pl, o) {
var allowed_tags = ['ul','li','b','p','table','tr','td'];
var allowed_attributes = ['href','colspan','rowspan'];
o.content = strip_tags(o.content,allowed_tags,allowed_attributes);
},
...
);