Export Multiple highcharts with custom text into pdf - pdf

I want to export multiple charts with textareas in PDF i
How will I implement in the following above code? pLease guide me

You can use my previous idea from similar topic:
Export highchart with free text entered as pdf
You can iterate over all of your charts and add them to your exported svg with texts related to these charts:
Highcharts.getSVG = function(charts, texts) {
var svgArr = [],
top = 0,
width = 0,
txt;
Highcharts.each(charts, function(chart, i) {
var svg = chart.getSVG();
svg = svg.replace('<svg', '<g transform="translate(0,' + top + ')" ');
svg = svg.replace('</svg>', '</g>');
top += chart.chartHeight;
width = Math.max(width, chart.chartWidth);
svgArr.push(svg);
txt = texts[i];
txt = '<text x= "' + 0 + '" y = "' + (top + 20) + '" styles = "' + txt.attributes.style.value + '">' + $(txt).val() + '</text>';
top += 60;
svgArr.push(txt);
});
return '<svg height="' + top + '" width="' + width + '" version="1.1" xmlns="http://www.w3.org/2000/svg">' + svgArr.join('') + '</svg>';
};
Here you can find an example how it can work: http://jsfiddle.net/6m2rneL8/32/

Related

Is it possible to set up a carousel/slide show to a list of 150 items which are retrieved from an external source

So I created a Pokedex (for my portfolio), anyhow I was wondering if it is possible to include a carousel within a modal that activates once it is clicked and the item data will be retrieved from an external API. Anyhow every time you call a new item it erased the modal body to fetch the new data.
//Function modal
let modalContainer = document.querySelector("#pokemon-modal");
function showModal(pokemon) {
let modalBody = $(".modal-body");
let modalTitle = $(".modal-title");
modalTitle.empty();
modalBody.empty();
// data-target ='#myCarousel'
//creating element for name
let nameElement = $("<h1>" + capitalizeFirstLetter(pokemon.name) + "</h1>");
//creating new img
let imageElementFront = $(
`<img alt="pokemon-image" src="${pokemon.imageUrl}" class="modal-img"
style="width:40%">`
);
//creating elemnt for height
let heightElement = $("<p>" + "Height: " + pokemon.height + "</p>");
//creating element for weight
let weightElement = $("<p>" + "Weight: " + pokemon.weight + "</p>");
//creating element for types
let pokemonTypes = [];
Object.keys(pokemon.types).forEach((key) => {
pokemonTypes.push(" " + pokemon.types[key].type.name);
});
let typesElement = $("<p>" + "Type(s): " + pokemonTypes + "</p>");
modalTitle.append(nameElement);
modalBody.append(imageElementFront);
modalBody.append(heightElement);
modalBody.append(weightElement);
modalBody.append(typesElement);
modalContainer.classList.add("is-visible");
$("#pokemonModal").modal("show");
}
This is just a portion of the code, but where I believe the problem exists to create such slideshow...
Any thoughts?

Create Google Script that saves sheet as pdf to specified folder in google drive

So thanks to other members I was able to piece together a script that does what I need except for 1 small hiccup. Rather than saving the single sheet as a pdf in the designated folder, it saves the entire workbook. I've tried multiple variations to get it to save just the sheet I want (named JSA) but it either gives me an error message or continues to download the whole spreadsheet. I'm sure it's something simple I'm missing, but I'm not as versed with Script as I am with writing Macros, so I'm stuck. The first part of the code, downloading it as a PDF works like a charm, it's the last section where I want it to save the PDF to a specified folder that's the issue. Any assistance would be appreciated.
function downloadPdf() {
var ss = SpreadsheetApp.getActive(),
id = ss.getId(),
sht = ss.getActiveSheet(),
shtId = sht.getSheetId(),
url =
'https://docs.google.com/spreadsheets/d/' +
id +
'/export' +
'?format=pdf&gid=' +
shtId
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=false' // orientation, false for landscape
+ '&scale=2' // 1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&fitw=true' // fit to width, false for actual size
+ '&top_margin=0.25' // All four margins must be set!
+ '&bottom_margin=0.25' // All four margins must be set!
+ '&left_margin=0.25' // All four margins must be set!
+ '&right_margin=0.25' // All four margins must be set!
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenum=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&horizontal_alignment=CENTER' //LEFT/CENTER/RIGHT
+ '&vertical_alignment=TOP'; //TOP/MIDDLE/
var val = SpreadsheetApp.getActive().getRange('H2').getValues();//custom pdf name here
var val2= Utilities.formatDate(SpreadsheetApp.getActive().getRange("N2").getValue(), ss.getSpreadsheetTimeZone(), "MM/dd/YY");
var val3= " - "
val += val3 += val2 += '.pdf';
//can't download with a different filename directly from server
//download and remove content-disposition header and serve as a dataURI
//Use anchor tag's download attribute to provide a custom filename
var res = UrlFetchApp.fetch(url, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
});
SpreadsheetApp.getUi().showModelessDialog(
HtmlService.createHtmlOutput(
'<a target ="_blank" download="' +
val +
'" href = "data:application/pdf;base64,' +
Utilities.base64Encode(res.getContent()) +
'">Click here</a> to download, if download did not start automatically' +
'<script> \
var a = document.querySelector("a"); \
a.addEventListener("click",()=>{setTimeout(google.script.host.close,10)}); \
a.click(); \
</script>'
).setHeight(50),
'Downloading PDF..'
);
const folderName = `Test`;
const fileNamePrefix = val += val3 += val2 += '.pdf';
var JSA = SpreadsheetApp.getActiveSpreadsheet();
var s = JSA.getSheetByName("JSA");
DriveApp.getFoldersByName(folderName)
.next()
.createFile(SpreadsheetApp.getActiveSpreadsheet()
.getBlob()
.getAs(`application/pdf`)
.setName(`${fileNamePrefix}`));
}
I believe your goal is as follows.
You want to create a PDF file, which is downloaded using the first part of your script, in the specific folder on Google Drive.
In this case, how about the following modification? I thought that res might be able to be used.
From:
var JSA = SpreadsheetApp.getActiveSpreadsheet();
var s = JSA.getSheetByName("JSA");
DriveApp.getFoldersByName(folderName)
.next()
.createFile(SpreadsheetApp.getActiveSpreadsheet()
.getBlob()
.getAs(`application/pdf`)
.setName(`${fileNamePrefix}`));
To:
DriveApp.getFoldersByName(folderName)
.next()
.createFile(res.getBlob().setName(`${fileNamePrefix}`));
In this modification, it supposes that sht = ss.getActiveSheet(), is JSA sheet. If the active sheet is not JSA sheet, please modify as follows.
To:
const url2 =
'https://docs.google.com/spreadsheets/d/' +
id +
'/export' +
'?format=pdf&gid=' +
ss.getSheetByName("JSA").getSheetId()
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=false' // orientation, false for landscape
+ '&scale=2' // 1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&fitw=true' // fit to width, false for actual size
+ '&top_margin=0.25' // All four margins must be set!
+ '&bottom_margin=0.25' // All four margins must be set!
+ '&left_margin=0.25' // All four margins must be set!
+ '&right_margin=0.25' // All four margins must be set!
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenum=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&horizontal_alignment=CENTER' //LEFT/CENTER/RIGHT
+ '&vertical_alignment=TOP'; //TOP/MIDDLE/
const res2 = UrlFetchApp.fetch(url2, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
});
DriveApp.getFoldersByName(folderName)
.next()
.createFile(res2.getBlob().setName(`${fileNamePrefix}`));
Reference:
fetch(url, params)

VTD-XML element fragment incorrect

When parsing a XML document (in UTF-8) containing a special character like © using VTD-XML I now encounter an issue that the returned element fragment (getElementFragment) is not correct.
Example code:
VTDGen vg = new VTDGen();
String xmlDocument =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<Root>\r\n" +
" <!-- © -->\r\n" +
" <SomeElement/>\r\n" +
"</Root>";
// For some reason with US_ASCII it does work, although the file is UTF-8.
vg.setDoc(xmlDocument.getBytes(StandardCharsets.UTF_8));
// True or false doesn't matter here, some result.
vg.parse(false);
// Find the element and its fragment.
VTDNav nv = vg.getNav();
AutoPilot ap = new AutoPilot(nv);
ap.selectXPath("//SomeElement");
while ((ap.evalXPath()) != -1) {
long elementOffset = nv.getElementFragment();
int contentStartIndex = (int)elementOffset;
int contentEndIndex = contentStartIndex + (int)(elementOffset>>32);
System.out.println("Returned fragment: " + contentStartIndex + ":" + contentEndIndex + ":\n'" + xmlDocument.substring(contentStartIndex, contentEndIndex) + "'");
}
This returns:
Returned fragment: 65:79:
'SomeElement/>
'
While when changing the StandardCharsets.UTF_8 into StandardCharsets.US_ASCII it does work:
Returned fragment: 64:78:
'<SomeElement/>'
When the input file is a UTF-8 file, this leads to incorrect behaviour. Can this be a bug in VTD-XML, or am I doing something wrong here?
The "©" is a two-word unicode char which causes the starting/ending unicode offset to drift from the starting/ending byte offset by 1. This is not a bug... below is the fix
while ((ap.evalXPath()) != -1) {
long elementOffset = nv.getElementFragment();
int contentStartIndex = (int)elementOffset;
int contentEndIndex = contentStartIndex + (int)(elementOffset>>32);
System.out.println("Returned fragment: " + contentStartIndex + ":" + contentEndIndex + ":\n'"
+ nv.toString(contentStartIndex,(int)(elementOffset>>32)));
//+ xmlDocument.substring(contentStartIndex, contentEndIndex) + "'");
}

Google Apps script created file is not PDF

I'm trying to create a PDF file with this code:
var name = "test.pdf";
var url = 'https://docs.google.com/spreadsheets/d/' + newSpreadsheetID + '/export?exportFormat=pdf&format=pdf' +
'&size=A4' +
'&portrait=true' +
'&fitw=true' + // fit to width, false for actual size
'&sheetnames=false&printtitle=false&pagenumbers=false' +
'&gridlines=false' +
'&fzr=false' + // do not repeat frozen rows on each page
'&gid='+SheetID; //the sheet's Id
var pdf = UrlFetchApp.fetch(url);
var pdf = pdf.getBlob().setName(name);
DocsList.createFile(pdf);
This code creates a file but the file contains just plain text, can you guys help me to get it into PDF format?
First off, DocsList was deprecated (https://developers.google.com/apps-script/reference/docs-list/docs-list). So I think we should use DriveApp this time.
I ignored the parameters you used to format the pdf, the script can be simply as -
var sheet = DriveApp.getFileById(spreadsheetId);
DriveApp.createFile(sheet.getAs("application/pdf"));
Please let me know if you want more elaboration. :)
I made a few changes and got your call working. I don't know where the documentation for the export settings are, but some of them don't work such as "gridlines". Also below is a 2 line example of the same thing.
function makePDF(){
var newSpreadsheetID = SpreadsheetApp.getActive().getId()
var SheetID="Sheet1";
var name = "test.pdf";
var url = 'https://docs.google.com/spreadsheets/d/' + newSpreadsheetID + '/export?exportFormat=pdf&format=pdf'; +
'&size=A4' +
'&portrait=true' +
'&fitw=true' + // fit to width, false for actual size
'&sheetnames=false&printtitle=false&pagenumbers=false' +
'&gridlines=false' +
'&fzr=false'; + // do not repeat frozen rows on each page
'&gid='+SheetID; //the sheet's Id
var pdf = UrlFetchApp.fetch(url,{headers: {authentication:"Bearer " + ScriptApp.getOAuthToken()}, muteHttpExceptions:true}).getBlob();
pdf.setName(name);
DriveApp.createFile(pdf);
}
function simplePDFConvert(){
var ss = SpreadsheetApp.openById( spreadSheetId );
DriveApp.createFile(ss.getBlob());
}

Way to suppress [Item not found] in Sitecore multilist selected items if due to permissions?

Our Sitecore content tree is generally split up into global and local (or country-specific) pages to serve customers of our branches. As you'd expect, the global pages show up for all viewers of our site, regardless of their geographic locale, but we have implemented certain fields on the global pages that are localizable, e.g. banner ads, featured content, etc.
We've set up security already so that, for a multilist, a given content editor only sees items on the left-hand side to which they have access. The thing that we're running into is that items chosen by other branch content editors are showing up in the right-hand "selected" area of the multilist and, if the content editor currently viewing the item doesn't have permissions to those, they're showing up as [Item not found]. We've had well-intentioned content editors mistakenly double-click those to remove them, not realizing they're removing content intentionally placed there by other editors. A screenshot of how this looks, using the view of one of our German content editors, is below:
What I am trying to determine is if there's a way, using security or other methods, to suppress the [Item not found] messages entirely for items to which the current content editor doesn't have permissions. Any hints for a good way to do this (if it's doable) would be appreciated.
You can create your own Multilist class inheriting from Sitecore.Shell.Applications.ContentEditor.MultilistEx class and override DoRender() method of this class. In a place where text [Item Not Found] is displayed, check if the item exists but user doesn't have access rights (by trying to retrieve the item with SecurityDisabler) and display proper message.
Then you need to go to core database and register your field type:
And finally switch the type of your field to the newly created type - your field will look like this:
The code below is the original reflected MultilistEx code which the changes you need:
using System.Collections;
using System.Web.UI;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Resources;
using Sitecore.SecurityModel;
namespace My.Assembly.Namespace
{
public class MyMultilistEx : Sitecore.Shell.Applications.ContentEditor.MultilistEx
{
protected override void DoRender(HtmlTextWriter output)
{
Assert.ArgumentNotNull(output, "output");
ArrayList selected;
IDictionary unselected;
GetSelectedItems(GetItems(Sitecore.Context.ContentDatabase.GetItem(ItemID)), out selected, out unselected);
ServerProperties["ID"] = ID;
string disabledMessage = string.Empty;
if (ReadOnly)
disabledMessage = " disabled=\"disabled\"";
output.Write("<input id=\"" + ID + "_Value\" type=\"hidden\" value=\"" + StringUtil.EscapeQuote(Value) + "\" />");
output.Write("<table" + GetControlAttributes() + ">");
output.Write("<tr>");
output.Write("<td class=\"scContentControlMultilistCaption\" width=\"50%\">" + Translate.Text("All") + "</td>");
output.Write("<td width=\"20\">" + Images.GetSpacer(20, 1) + "</td>");
output.Write("<td class=\"scContentControlMultilistCaption\" width=\"50%\">" + Translate.Text("Selected") + "</td>");
output.Write("<td width=\"20\">" + Images.GetSpacer(20, 1) + "</td>");
output.Write("</tr>");
output.Write("<tr>");
output.Write("<td valign=\"top\" height=\"100%\">");
output.Write("<select id=\"" + ID + "_unselected\" class=\"scContentControlMultilistBox\" multiple=\"multiple\" size=\"10\"" + disabledMessage + " ondblclick=\"javascript:scContent.multilistMoveRight('" + ID + "')\" onchange=\"javascript:document.getElementById('" + ID + "_all_help').innerHTML=selectedIndex>=0?options[selectedIndex].innerHTML:''\" >");
foreach (DictionaryEntry dictionaryEntry in unselected)
{
Item unselectedItem = dictionaryEntry.Value as Item;
if (unselectedItem != null)
output.Write("<option value=\"" + GetItemValue(unselectedItem) + "\">" + unselectedItem.DisplayName + "</option>");
}
output.Write("</select>");
output.Write("</td>");
output.Write("<td valign=\"top\">");
RenderButton(output, "Core/16x16/arrow_blue_right.png", "javascript:scContent.multilistMoveRight('" + ID + "')");
output.Write("<br />");
RenderButton(output, "Core/16x16/arrow_blue_left.png", "javascript:scContent.multilistMoveLeft('" + ID + "')");
output.Write("</td>");
output.Write("<td valign=\"top\" height=\"100%\">");
output.Write("<select id=\"" + ID + "_selected\" class=\"scContentControlMultilistBox\" multiple=\"multiple\" size=\"10\"" + disabledMessage + " ondblclick=\"javascript:scContent.multilistMoveLeft('" + ID + "')\" onchange=\"javascript:document.getElementById('" + ID + "_selected_help').innerHTML=selectedIndex>=0?options[selectedIndex].innerHTML:''\">");
for (int index = 0; index < selected.Count; ++index)
{
Item selectedItem = selected[index] as Item;
if (selectedItem != null)
{
output.Write("<option value=\"" + GetItemValue(selectedItem) + "\">" + selectedItem.DisplayName + "</option>");
}
else
{
string path = selected[index] as string;
if (path != null)
{
string optionDisabled = string.Empty;
Item linkedItem = Sitecore.Context.ContentDatabase.GetItem(path);
Item notAccessibleItem;
using (new SecurityDisabler())
{
notAccessibleItem = Sitecore.Context.ContentDatabase.GetItem(path);
}
string text;
if (linkedItem == null && notAccessibleItem != null)
{
text = notAccessibleItem.DisplayName + " [You don't have access rights to this item]";
optionDisabled = " disabled=\"disabled\"";
}
else
{
text = linkedItem == null
? path + ' ' + Translate.Text("[Item not found]")
: linkedItem.DisplayName + ' ' + Translate.Text("[Not in the selection List]");
}
output.Write("<option value=\"" + path + "\"" + optionDisabled + ">" + text + "</option>");
}
}
}
output.Write("</select>");
output.Write("</td>");
output.Write("<td valign=\"top\">");
RenderButton(output, "Core/16x16/arrow_blue_up.png", "javascript:scContent.multilistMoveUp('" + ID + "')");
output.Write("<br />");
RenderButton(output, "Core/16x16/arrow_blue_down.png", "javascript:scContent.multilistMoveDown('" + ID + "')");
output.Write("</td>");
output.Write("</tr>");
output.Write("<tr>");
output.Write("<td valign=\"top\">");
output.Write("<div style=\"border:1px solid #999999;font:8pt tahoma;padding:2px;margin:4px 0px 4px 0px;height:14px\" id=\"" + ID + "_all_help\"></div>");
output.Write("</td>");
output.Write("<td></td>");
output.Write("<td valign=\"top\">");
output.Write("<div style=\"border:1px solid #999999;font:8pt tahoma;padding:2px;margin:4px 0px 4px 0px;height:14px\" id=\"" + ID + "_selected_help\"></div>");
output.Write("</td>");
output.Write("<td></td>");
output.Write("</tr>");
output.Write("</table>");
}
private void RenderButton(HtmlTextWriter output, string icon, string click)
{
Assert.ArgumentNotNull(output, "output");
Assert.ArgumentNotNull(icon, "icon");
Assert.ArgumentNotNull(click, "click");
ImageBuilder imageBuilder = new ImageBuilder();
imageBuilder.Src = icon;
imageBuilder.Width = 16;
imageBuilder.Height = 16;
imageBuilder.Margin = "2px";
if (!ReadOnly)
imageBuilder.OnClick = click;
output.Write((imageBuilder).ToString());
}
}
}