I'm trying to send multiple files from one folder to printer.
Now, I can send just one file from folder to printer. However I want to print the files from the folder. I'm using ASPOSE.PDF
I was trying to modify the following code but without success:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aspose.Pdf;
using System.Drawing;
using Aspose.Pdf.Facades;
namespace Printer
class Program
{
static void Main(string[] args)
{
PdfViewer viewer = new PdfViewer();
viewer.BindPdf(#"C:\Printing\Hello.pdf");
System.Drawing.Printing.PrinterSettings printersetting = new System.Drawing.Printing.PrinterSettings();
printersetting.Copies = 1; //specify number of copies
printersetting.PrinterName = "Conan-printer"; // name of default printer to be used
System.Drawing.Printing.PageSettings pagesetting = new System.Drawing.Printing.PageSettings();
pagesetting.PaperSource = printersetting.PaperSources[1]; //assign paper source to pagesettings object
//you can either specify the index of the tray or you can loop through the trays as well.
viewer.PrintDocumentWithSettings(pagesetting, printersetting);
viewer.Close();
}
}
}
You can copy the above code to a new method, that accepts the pdf file path as argument.
In the main method, load files from a folder and then call the method for each file. Below is an example.
// Load pdf files from a folder
string folderPath = #"E:\Loans\cirruslsdemo\HICODistributing";
string[] files = Directory.GetFiles(folderPath, "*.pdf");
// Print pdf files one by one
foreach (string pdfFile in files)
{
printDocument(pdfFile);
}
private void printDocument(string pdfFile)
{
PdfViewer viewer = new PdfViewer();
viewer.BindPdf(pdfFile);
System.Drawing.Printing.PrinterSettings printersetting = new System.Drawing.Printing.PrinterSettings();
printersetting.Copies = 1; //specify number of copies
printersetting.PrinterName = "Conan-printer"; // name of default printer to be used
System.Drawing.Printing.PageSettings pagesetting = new System.Drawing.Printing.PageSettings();
pagesetting.PaperSource = printersetting.PaperSources[1]; //assign paper source to pagesettings object
//you can either specify the index of the tray or you can loop through the trays as well.
viewer.PrintDocumentWithSettings(pagesetting, printersetting);
viewer.Close();
}
Related
I'm working in my own PDF Reader using C# & Patagames/PDFium library and I am able to open files using "OpenFileDialog" and show them on the screen. However, due requirements of the boss I am not allowed to have any buttons in the screen. All we want is to click the any .PDF file (For example, in this route: C:\Users\Adaptabilidad\Desktop\Test.pdf) and launch it & show the PDF document directly, without looking for the directory of the file. I've set my ".exe" as default app, although, the PDF Reader is executed no PDF file is displayed.
I've tried Application.ExecutablePath, Application.StartUpPath after initializing the component and I'm still getting the route of my PDF reader executable (.Exe) but I need to know what the file to be open is (filepath).
How can I get the information about the .pdf file (directory can vary) that is launching my app? You can see my code below if helps.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Patagames;
using System.IO;
namespace aPDF
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "PDF Files (*.pdf)|*.pdf";
if (dialog.ShowDialog() == DialogResult.OK)
{
openfile(dialog.FileName);
}
}
public void openfile(string filepath)
{
byte[] bytes = System.IO.File.ReadAllBytes(filepath);
var stream = new MemoryStream(bytes);
Patagames.Pdf.Net.PdfDocument pdfDocument = Patagames.Pdf.Net.PdfDocument.Load(stream);
pdfViewer1.Document = pdfDocument;
}
}
}
Updates:
I've found a way. One of you guys that commented allowed me to find out how to do it.
What I used is the following sentence in my Program.cs:
public static string[] cmdLine = Environment.GetCommandLineArgs();
public static string cmd = cmdLine[1];
Then, y use "cmd" as filepath.
Why? Environment.GetCommandLineArgs(); returns 2 values, the .exe you're executing (your program) & as second value the file that you've used in order to launch that .exe.
That's it. Thank you for your answers.
So i came up with C# code that goes to a directory, searches for the PDF file name and its complimentary PDF File that has a _1 and merges those into a folder within that directory called "Merge"
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
//private const string dir = #"C:\Users\XBorja\Desktop\IMAGES\";
static void Main(string[] args)
{
Console.WriteLine("Please Enter Location");
var dir = Console.ReadLine();
File.SetAttributes(dir, FileAttributes.Normal);
string[] files = Directory.GetFiles(dir, "*.pdf");
IEnumerable<IGrouping<string, string>> groups = files.GroupBy(n => n.Split('.')[0].Split('_')[0]);
//string f = files[0].Split('_')[0];
foreach (var items in groups)
{
Console.WriteLine(items.Key);
PdfDocument outputPDFDocument = new PdfDocument();
foreach (var pdfFile in items)
{
Merge(outputPDFDocument, pdfFile);
}
outputPDFDocument.Save(Path.GetDirectoryName(items.Key) + #"\Merge\" + Path.GetFileNameWithoutExtension(items.Key) + ".pdf");
}
Console.ReadKey();
}
private static void Merge(PdfDocument outputPDFDocument, string pdfFile)
{
PdfDocument inputPDFDocument = PdfReader.Open(pdfFile, PdfDocumentOpenMode.Import);
outputPDFDocument.Version = inputPDFDocument.Version;
foreach (PdfPage page in inputPDFDocument.Pages)
{
outputPDFDocument.AddPage(page);
}
}
}
}
This works great but i would prefer if instead of it being hard coded that it prompts the user by asking which/where the directory is that the PDF's are located to merge. Then once it does that, ask the user what the new subfolder will be named that the merged pdf's will go to.
I'm fairly new to C#
Without validation and so forth, to get the user to supply the info is simply :
Console.WriteLine("Please enter location");
var location = Console.ReadLine();
I am very very novice to c# and .net and trying to understand it.
I am using solution from how to read all files inside particular folder and trying to apply in my below code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace HowToCopyTextFiles
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
foreach (string txtName in Directory.GetFiles(#"C:\Users\Environ ment\Desktop\newfolder","*.rtf"))
{
using (StreamReader sr = new StreamReader(txtName))
{
sb.Append(sr.ReadToEnd());
sb.AppendLine();
}
}
Console.Write(sb.ToString());
Console.ReadLine();
}
}
}
The result is ok but at the end of my test file it shows environment name.
like.
this is content of first file
this is content of second file
↑My environment full name ↑My
environment full name ↑My environment full name (Yes 3 times)
I am using cs-script, Is it due to that?
While using .txt files, it is working fine. so the question is how to properly open .rtf files as text stream?
If rtf file is opened, it sometimes saves super hidden(not visible even show hidden file option) temp file as ~filename.rtf which is also read by c#.
I used code from here: C# - Get a list of files excluding those that are hidden
DirectoryInfo directory = new DirectoryInfo(#"C:\temp");
FileInfo[] files = directory.GetFiles();
var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));
foreach (var f in filtered)
{
Debug.WriteLine(f);
}
This solved my problem.
XPS Printer allows us to create xps file no matter if from an image or txt or doc file.
I would like to do the same just programmatically in c#.
How do I send a file to xps printer and let the printer convert it to .xps file?
Any ideas?
I Google this but haven't found much so far.
It is possible also to use print queue to print to the XPS document writer but it will always show the file dialog.
See below other alternatives to convert and print to XPS file.
Programmatically converting files to XPS
This is not as simple as you wish many users out there have tried and there is many different ways to accomplish it all which arent the best.
One way (easiest way) to convert documents to XPS would be to use WORD 2007+ API to do it.
See below a snipped from this MSDN forum question
To programmatically convert docx to xps using Word 2007 see
Document.ExportAsFixedFormat in the Word Object Model Reference
(http://msdn2.microsoft.com/en-us/library/Bb256835.aspx). However,
since this is a server-side scenario you should take note of KB 257757
Considerations for server-side Automation of Office (see
http://support.microsoft.com/kb/257757).
Printing Images to XPS
You can easily print an Image to XPS file using the code below.
The code below is WPF example the image you pass into the write method needs to be wrapped in a canvas see this post for an example: http://denisvuyka.wordpress.com/2007/12/03/wpf-diagramming-saving-you-canvas-to-image-xps-document-or-raw-xaml/
XpsDocument xpsd = new XpsDocument("C:\\YourXPSFileName.xps", FileAccess.ReadWrite);
System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd);
xw.Write(YourImageYouWishToWrite);
See an extended example below:
public void Export(Uri path, Canvas surface)
{
if (path == null) return;
// Save current canvas transorm
Transform transform = surface.LayoutTransform;
// Temporarily reset the layout transform before saving
surface.LayoutTransform = null;
// Get the size of the canvas
Size size = new Size(surface.Width, surface.Height);
// Measure and arrange elements
surface.Measure(size);
surface.Arrange(new Rect(size));
// Open new package
Package package = Package.Open(path.LocalPath, FileMode.Create);
// Create new xps document based on the package opened
XpsDocument doc = new XpsDocument(package);
// Create an instance of XpsDocumentWriter for the document
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
// Write the canvas (as Visual) to the document
writer.Write(surface);
// Close document
doc.Close();
// Close package
package.Close();
// Restore previously saved layout
surface.LayoutTransform = transform;
}
There are third party tools that allow you to print PDFs and other file formats to XPS.
PDF to XPS
Printing XPS files
It is possible to print XPS Documents programmatically You will need .Net 4 at least for this solution.
The example below uses the Print dialog from WPF and some of the classes from System.Windows.Xps and System.Printing.
The code below will print the Xps file to the default printer on the system however if you want to print to a different printer or even print to a print server you need to change the PrintQueue object on the print dialog.
Which is quite simple using the System.Printing namespace.
See the example below.
Please bear in mind that because it is using the WPF dialog it needs to run on a STATThread model.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Xps.Packaging;
namespace ConsoleApplication
{
class Program
{
[STAThread]
static void Main(string[] args)
{
PrintDialog dlg = new PrintDialog();
XpsDocument xpsDoc = new XpsDocument(#"C:\DATA\personal\go\test.xps", System.IO.FileAccess.Read);
dlg.PrintDocument(xpsDoc.GetFixedDocumentSequence().DocumentPaginator, "Document title");
}
}
}
See below some Helpful links.
Xps Document documentation
Print Dialog from WPF documentation
System.Printing namespace documentation
Hope this helps and fit your needs
class Program
{
[System.MTAThreadAttribute()] // Added for clarity, but this line is redundant because MTA is the default.
static void Main(string[] args)
{
// Create the secondary thread and pass the printing method for
// the constructor's ThreadStart delegate parameter. The BatchXPSPrinter
// class is defined below.
Thread printingThread = new Thread(BatchXPSPrinter.PrintXPS);
// Set the thread that will use PrintQueue.AddJob to single threading.
printingThread.SetApartmentState(ApartmentState.STA);
// Start the printing thread. The method passed to the Thread
// constructor will execute.
printingThread.Start();
}//end Main
}//end Program class
public class BatchXPSPrinter
{
public static void PrintXPS()
{
// Create print server and print queue.
LocalPrintServer localPrintServer = new LocalPrintServer();
PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
// Prompt user to identify the directory, and then create the directory object.
Console.Write("Enter the directory containing the XPS files: ");
String directoryPath = Console.ReadLine();
DirectoryInfo dir = new DirectoryInfo(directoryPath);
// If the user mistyped, end the thread and return to the Main thread.
if (!dir.Exists)
{
Console.WriteLine("There is no such directory.");
}
else
{
// If there are no XPS files in the directory, end the thread
// and return to the Main thread.
if (dir.GetFiles("*.xps").Length == 0)
{
Console.WriteLine("There are no XPS files in the directory.");
}
else
{
Console.WriteLine("\nJobs will now be added to the print queue.");
Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.");
// Batch process all XPS files in the directory.
foreach (FileInfo f in dir.GetFiles("*.xps"))
{
String nextFile = directoryPath + "\\" + f.Name;
Console.WriteLine("Adding {0} to queue.", nextFile);
try
{
// Print the Xps file while providing XPS validation and progress notifications.
PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob(f.Name, nextFile, false);
}
catch (PrintJobException e)
{
Console.WriteLine("\n\t{0} could not be added to the print queue.", f.Name);
if (e.InnerException.Message == "File contains corrupted data.")
{
Console.WriteLine("\tIt is not a valid XPS file. Use the isXPS Conformance Tool to debug it.");
}
Console.WriteLine("\tContinuing with next XPS file.\n");
}
}// end for each XPS file
}//end if there are no XPS files in the directory
}//end if the directory does not exist
Console.WriteLine("Press Enter to end program.");
Console.ReadLine();
}// end PrintXPS method
}// end BatchXPSPrinter class
Using the answers in How to merge PDFs into a PDF Portfolio?, I've been able to create an PDF portfolio using iTextSharp. However, using Adobe Acrobat I'm able to create folders, and I'm able to put files in those folders.
How do I create folders and how do I put files in those folders in a PDF portfolio using iTextSharp?
I've tried using a pdf inspector program to see the differences between a portfolio with and without folders, but I haven't been able to see any. I guess I'm looking in the wrong places
EDIT
For this specific use case of mine it is actually possible to create the PDF portfolio with folder up front. So it's way more important to be able to insert files in folders in an existing PDF portfolio as opposed to actually creating the folders themselves.
Here is some proof of concept code that creates a new portfolio pdf with couple of folders and inserts an existing pdf file into each of those folders. This approach is based on using a text editor to look at a pdf file created using the sample code linked to in the original post, then using Acrobat to create a folder and move the embedded file into that folder, saving the pdf, then looking at the changes with a text editor. In the code I'm recreating the changes found while comparing the two versions of the portfolio pdf, so while it works (at least on my machine), it may not be the best way to accomplish the task.
If you want to view the before/after files like I did, create the portfolio using iTextsharp, then open with Acrobat and create a folder and move the embedded file(s) into the folder, then just save the file again using the save icon on the toolbar. Do not use the File -> Save As... option to save the file as a Portfolio PDF. Acrobat reorganizes the file and compresses or in some other way converts a lot of the file to binary data that you won't be able read in a text editor. I found that deleting the binary stream data made the structure much easier to follow. Just get rid of everything between each pair of stream/endstream keywords.
One thing that Acrobat does in portfolio pdfs is embed a flash file that provides animation and a more attractive theme for the portfolio. I wasn't able to figure out how to do that, so the resulting file from this code is a bit plain looking.
using System;
using System.IO;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.collection;
public class FolderWriter {
private const string Folder = #"C:\Path\to\your\pdf\files";
private const string File1 = #"Pdf File 1.pdf";
private const string File2 = #"Pdf File 2.pdf";
private readonly string file1Path = Path.Combine(Folder, File1);
private readonly string file2Path = Path.Combine(Folder, File2);
private readonly string[] keys = new[] {
"Type",
"File"
};
public void Write(Stream stream) {
using (Document document = new Document()) {
PdfWriter writer = PdfWriter.GetInstance(document, stream);
document.Open();
document.Add(new Paragraph("This document contains a collection of PDFs"));
PdfIndirectReference parentFolderObjectReference = writer.PdfIndirectReference;
PdfIndirectReference childFolder1ObjectReference = writer.PdfIndirectReference;
PdfIndirectReference childFolder2ObjectReference = writer.PdfIndirectReference;
PdfDictionary parentFolderObject = GetFolderDictionary(0);
parentFolderObject.Put(new PdfName("Child"), childFolder1ObjectReference);
parentFolderObject.Put(PdfName.NAME, new PdfString());
PdfDictionary childFolder1Object = GetFolderDictionary(1);
childFolder1Object.Put(PdfName.NAME, new PdfString("Folder 1"));
childFolder1Object.Put(PdfName.PARENT, parentFolderObjectReference);
childFolder1Object.Put(PdfName.NEXT, childFolder2ObjectReference);
PdfDictionary childFolder2Object = GetFolderDictionary(2);
childFolder2Object.Put(PdfName.NAME, new PdfString("Folder 2"));
childFolder2Object.Put(PdfName.PARENT, parentFolderObjectReference);
PdfCollection collection = new PdfCollection(PdfCollection.DETAILS);
PdfCollectionSchema schema = CollectionSchema();
collection.Schema = schema;
collection.Sort = new PdfCollectionSort(keys);
collection.Put(new PdfName("Folders"), parentFolderObjectReference);
writer.Collection = collection;
PdfFileSpecification fs;
PdfCollectionItem item;
fs = PdfFileSpecification.FileEmbedded(writer, file1Path, File1, null);
item = new PdfCollectionItem(schema);
item.AddItem("Type", "pdf");
fs.AddCollectionItem(item);
// the description is apparently used to place the
// file in a particular folder. The number between the < and >
// is used to put the file in the folder that has the matching id
fs.AddDescription(GetDescription(1, File1), false);
writer.AddFileAttachment(fs);
fs = PdfFileSpecification.FileEmbedded(writer, file2Path, File2, null);
item = new PdfCollectionItem(schema);
item.AddItem("Type", "pdf");
fs.AddCollectionItem(item);
fs.AddDescription(GetDescription(2, File2), false);
writer.AddFileAttachment(fs);
writer.AddToBody(parentFolderObject, parentFolderObjectReference);
writer.AddToBody(childFolder1Object, childFolder1ObjectReference);
writer.AddToBody(childFolder2Object, childFolder2ObjectReference);
document.Close();
}
}
private static string GetDescription(int id, string fileName) {
return string.Format("<{0}>{1}", id, fileName);
}
private static PdfDictionary GetFolderDictionary(int id) {
PdfDictionary dic = new PdfDictionary(new PdfName("Folder"));
dic.Put(PdfName.CREATIONDATE, new PdfDate(DateTime.Now));
dic.Put(PdfName.MODDATE, new PdfDate(DateTime.Now));
dic.Put(PdfName.ID, new PdfNumber(id));
return dic;
}
private static PdfCollectionSchema CollectionSchema() {
PdfCollectionSchema schema = new PdfCollectionSchema();
PdfCollectionField type = new PdfCollectionField("File type", PdfCollectionField.TEXT);
type.Order = 0;
schema.AddField("Type", type);
PdfCollectionField filename = new PdfCollectionField("File", PdfCollectionField.FILENAME);
filename.Order = 1;
schema.AddField("File", filename);
return schema;
}
}
iTextsharp can't create folders, but you can create and find PDF bookmark.
See:
http://www.mikesdotnetting.com/Article/84/iTextSharp-Links-and-Bookmarks
http://www.geek-tutorials.com/java/itext/itext_bookmark_anchor.php