How to print a file with Jscript - windows-7-x64

Goal
I want to print a file via a PDF printer which isn't the default printer. I was able to temporary change the normal printer to the PDF printer.
Problem
But I don't know how to print a .doc, .txt or .xls via Jscript. Also, I can't find a way to save the default printer name so I can switch back after I've printed the file.
Jscript code
var objShell = new ActiveXObject("Shell.Application");
var objFSO = new ActiveXObject("Scripting.FileSystemObject");
try {
var PDFCreatorQueue = new ActiveXObject("PDFCreatorBeta.JobQueue");
PDFCreatorQueue.Initialize();
var sourceFile = WScript.Arguments(0)
var sourceFolder = objFSO.GetParentFolderName(sourceFile)
var sourceName = objFSO.GetBaseName(sourceFile)
var targetFile = sourceFolder + "\\" + sourceName + ".pdf"
//HERE GOES THE COMMAND TO SAVE THE CURRENT DEFAULT PRINTER NAME TO A TEMP VARIABLE
objNet.SetDefaultPrinter("PDFCreator");
//HERE GOES THE PRINT COMMAND WHICH I DON'T KNOW
// HERE GOES THE COMMAND TO CHANGE BACK TO THE OLD DEFAULT PRINTER
if(!PDFCreatorQueue.WaitForJob(3)) {
WScript.Echo("The print job did not reach the queue within " + 3 + " seconds");
}
else {
var job = PDFCreatorQueue.NextJob;
job.SetProfileByGUID("DefaultGuid");
job.ConvertTo(targetFile);
if(!job.IsFinished || !job.IsSuccessful) {
WScript.Echo("Could not convert the file: " + targetFile);
}
}
PDFCreatorQueue.ReleaseCom();
}
catch(e) {
WScript.Echo(e.message);
PDFCreatorQueue.ReleaseCom();
}

Use the ShellFolderItem.InvokeVerbEx() function. The JScript example code in the MSDN article shows how to use it. Make the first argument "print" and the second argument the name of the printer. So you can remove the code that tinkers with the default printer.

Printing web page from js is quite easy, you could use window.print() method over an iFrame ( this works only with file format wich can be displaied into a web page so it doesn't work with .doc extension)
<iframe id="textfile" src="text.txt"></iframe>
<button onclick="print()">Print</button>
<script type="text/javascript">
function print() {
var iframe = document.getElementById('textfile');
iframe.contentWindow.print();
}
</script>
These will show you a message box to select what printer you want to use a so on.
What are you asking for seems to be silent printing but it isn't standarized over all the broswer.
P.S. I think that isn't a good idea to use the printer to save this file to pdf, I think taht you could look at jsPDF (a js tools to create pdf) or you should consider to make the pdf generation serverside.

Related

Select HtmlToPdf - Html page saved in development and not saved but shown in production

I've got a problem with saving and NOT displaying a page that I want converted to pdf. The code I use works fine from within Visual Studio but not from IIS. On the development machine it converts the HTML page, saves the pdf and then redirects. On a 'production' machine with IIS it shows the html page (FactuurPDF) but stops there.
What I want is the behaviour on the development machine.
This is my code:
// other stuff
HtmlToPdf converter = new HtmlToPdf();
var TxtUrl = "";
TxtUrl = "https://localhost:44368/Facturen/FactuurPDF" + "?id=" + id + "&fact=" + fact;
PdfDocument doc = converter.ConvertUrl(TxtUrl);
var dat = DateTime.Today.ToString("yyyy-MM-dd");
doc.Save(#Path.Combine(_env.WebRootPath, "Verzondenfacturen/Fact_" + id + "_" + dat + ".pdf"));
doc.Close();
//other stuff (email pdf and update database)
return LocalRedirect("/Facturen/Index");
I hope anybody has a clue.
Setting the converter.Options.MaxPageLoadTime = 10 solved the problem.

Protractor - Create a txt file as report with the "Expect..." result

I'm trying to create a report for my scenario, I want to execute some validations and add the retults in a string, then, write this string in a TXT file (for each validation I would like to add the result and execute again till the last item), something like this:
it ("Perform the loop to search for different strings", function()
{
browser.waitForAngularEnabled(false);
browser.get("http://WebSite.es");
//strings[] contains 57 strings inside the json file
for (var i = 0; i == jsonfile.strings.length ; ++i)
{
var valuetoInput = json.Strings[i];
var writeInFile;
browser.wait;
httpGet("http://website.es/search/offers/list/"+valuetoInput+"?page=1&pages=3&limit=20").then(function(result) {
writeInFile = writeInFile + "Validation for String: "+ json.Strings[i] + " Results is: " + expect(result.statusCode).toBe(200) + "\n";
});
if (i == jsonfile.strings.length)
{
console.log("Executions finished");
var fs = require('fs');
var outputFilename = "Output.txt";
fs.writeFile(outputFilename, "Validation of Get requests with each string:\n " + writeInFile, function(err) {
if(err)
{
console.log(err);
}
else {
console.log("File saved to " + outputFilename);
}
});
}
};
});
But when I check my file I only get the first row writen in the way I want and nothing else, could you please let me know what am I doing wrong?
*The validation works properly in the screen for each of string in my file used as data base
**I'm a newbie with protractor
Thank you a lot!!
writeFile documentation
Asynchronously writes data to a file, replacing the file if it already
exists
You are overwriting the file every time, which is why it only has 1 line.
The easiest way would probably (my opinion) be appendFile. It writes to a file without overwriting existing data and will also create the file if it doesnt exist in the first place.
You could also re-read that log file, store that data in a variable, and re-write to that file with the old AND new data included in it. You could also create a writeStream etc.
There are quite a few ways to go about it and plenty of other answers
on SO specifically on those functions that can provide more info.
Node.js Write a line into a .txt file
Node.js read and write file lines
Final note, if you are using Jasmine you can also create a custom jasmine reporter. They have methods that contain exactly what you want (status Pass/Fail, actual vs expected values etc) and it's fairly easy to set up with Protractor

How to edit pasted content using the Open XML SDK

I have a custom template in which I'd like to control (as best I can) the types of content that can exist in a document. To that end, I disable controls, and I also intercept pastes to remove some of those content types, e.g. charts. I am aware that this content can also be drag-and-dropped, so I also check for it later, but I'd prefer to stop or warn the user as soon as possible.
I have tried a few strategies:
RTF manipulation
Open XML manipulation
RTF manipulation is so far working fairly well, but I'd really prefer to use Open XML as I expect it to be more useful in the future. I just can't get it working.
Open XML Manipulation
The wonderfully-undocumented (as far as I can tell) "Embed Source" appears to contain a compound document object, which I can use to modify the copied content using the Open XML SDK. But I have been unable to put the modified content back into an object that lets it be pasted correctly.
The modification part seems to work fine. I can see, if I save the modified content to a temporary .docx file, that the changes are being made correctly. It's the return to the clipboard that seems to be giving me trouble.
I have tried assigning just the Embed Source object back to the clipboard (so that the other types such as RTF get wiped out), and in this case nothing at all gets pasted. I've also tried re-assigning the Embed Source object back to the clipboard's data object, so that the remaining data types are still there (but with mismatched content, probably), which results in an empty embedded document getting pasted.
Here's a sample of what I'm doing with Open XML:
using OpenMcdf;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
...
object dataObj = Forms.Clipboard.GetDataObject();
object embedSrcObj = dateObj.GetData("Embed Source");
if (embedSrcObj is Stream)
{
// read it with OpenMCDF
Stream stream = embedSrcObj as Stream;
CompoundFile cf = new CompoundFile(stream);
CFStream cfs = cf.RootStorage.GetStream("package");
byte[] bytes = cfs.GetData();
string savedDoc = Path.GetTempFileName() + ".docx";
File.WriteAllBytes(savedDoc, bytes);
// And then use the OpenXML SDK to read/edit the document:
using (WordprocessingDocument openDoc = WordprocessingDocument.Open(savedDoc, true))
{
OpenXmlElement body = openDoc.MainDocumentPart.RootElement.ChildElements[0];
foreach (OpenXmlElement ele in body.ChildElements)
{
if (ele is Paragraph)
{
Paragraph para = (Paragraph)ele;
if (para.ParagraphProperties != null && para.ParagraphProperties.ParagraphStyleId != null)
{
string styleName = para.ParagraphProperties.ParagraphStyleId.Val;
Run run = para.LastChild as Run; // I know I'm assuming things here but it's sufficient for a test case
run.RunProperties = new RunProperties();
run.RunProperties.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("test"));
}
}
// etc.
}
openDoc.MainDocumentPart.Document.Save(); // I think this is redundant in later versions than what I'm using
}
// repackage the document
bytes = File.ReadAllBytes(savedDoc);
cf.RootStorage.Delete("Package");
cfs = cf.RootStorage.AddStream("Package");
cfs.Append(bytes);
MemoryStream ms = new MemoryStream();
cf.Save(ms);
ms.Position = 0;
dataObj.SetData("Embed Source", ms);
// or,
// Clipboard.SetData("Embed Source", ms);
}
Question
What am I doing wrong? Is this just a bad/unworkable approach?

perl hash table and javascript var

I have a CGI script,
I want to enter a valus from perl hash table to java script var tt.
(I mentioned in the code what works and what does not)
perl:
%devices;
push #{$devices{$entity} }, $fname;
js:
\$('#example tr').click(function(){
\$(this, 'tr').each(function(index, tr) {
var lines = \$('td', tr).map(function(index, td) {
return \$(td).text();
});
var d = lines[0];
var test = '#{$devices{'192.116.153.32'}}'; // working
var tt = '\#\{\$devices{' + "\'" + d + "\'" + "\}\}"; // Not working
alert(tt);
The Alert will print something like:
{"192.116.153.32":["examle1.txt","examle2.txt",...]}
JavaScript and Perl are different languages. The JS code and the CGI script will run on different computers.
The CGI script creates a page that is then transmitted to the browser. It does not matter what kind of data this page is, any JS code is just plain data for this script. For example, your snippet might become
$('#example tr').click(function(){
$(this, 'tr').each(function(index, tr) {
var lines = $('td', tr).map(function(index, td) {
return $(td).text();
});
var d = lines[0];
var test = 'the corresponding device'; // working
var tt = '#{$devices{' + "'" + d + "'" + "}}"; // Not working
alert(tt);
This is what the browser sees. The Perl code has no meaning to the browser.
The browser then renders the page and executes any JS scripts. At this point, there is no connection to the CGI script any more.
If you want a connection to the server, you can use AJAX requests. Note however that the first CGI script that generated the page will have terminated by then, so all variables are lost – you need to store any data in a database.
You can use JSON module in Perl to convert reference to the Perl hash to the string containing JavaScript associated array:
use JSON; # imports encode_json, decode_json, to_json and from_json.
# simple and fast interfaces (expect/generate UTF-8)
$utf8_encoded_json_text = encode_json \%devices;
js:
\$('#example tr').click(function(){
\$(this, 'tr').each(function(index, tr) {
var lines = \$('td', tr).map(function(index, td) {
return \$(td).text();
});
var d = lines[0];
var test = '#{$devices{'192.116.153.32'}}'; // working
var tt = '$utf8_encoded_json_text'; // working
alert(tt);
The Alert will print something like:
{"192.116.153.32":["examle1.txt","examle2.txt",...]}

ASP.net MVC wkhtmltopdf system process font issue

I'm using the wkhtmltopdf application to convert my ASP.net MVC 2 rendered HTML into a PDF and display the PDF instead of the standard view for better print ability. Everything works great minus one thing. When I run wkhtmltopdf as a process in my MVC application on our webserver it does not display the installed barcode font in the PDF.
Here is the code for the process.
public void HtmlToPdf(string url, string appPath)
{
string message = null;
// to build command argument
StringBuilder argument = new StringBuilder();
// input html file
string switches = "";
switches += "--print-media-type ";
switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm ";
switches += "--page-size Letter ";
switches += "--load-error-handling ignore ";
switches += "--username admin ";
switches += "--password pass ";
argument.Append(switches + " " + url + " " + "C:\\PDF\\temp.pdf");
// to call the exe to convert
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = "C:\\wkhtmltopdf\\wkhtmltopdf.exe";
p.StartInfo.WorkingDirectory = "C:\\wkhtmltopdf";
p.StartInfo.Arguments = argument.ToString();
p.Start();
p.WaitForExit();
message = p.StandardError.ReadToEnd();
if (string.IsNullOrEmpty(message))
{
message = p.StandardOutput.ReadToEnd();
}
else
{
System.Diagnostics.Debug.WriteLine(message);
}
}
Not really sure why it wont show the barcode because it shows in the when you render the html but not in when the wkhtmltopddf converts it to pdf. It also works correctly if you run wkhtmltopdf out side of my MVC application.
-Thanks for any help
Have you tried it in a while with an updated version of wkhtmltopdf?
Which version was this a problem with? I recently tried to generate using a random font I downloaded and it worked fine.
If you generate the PDF on a server the server needs the font too, I assume you know that but someone else reading might not realize it :)
Could I get the font in question to test on my system?
Was the conversion done in what environment? (Most likely not Linux due to asp.net, but asking just in case)