C2019-012: Merge pdfs
This commit is contained in:
220
PROMS/Volian.Print.Library/MergedPdf.cs
Normal file
220
PROMS/Volian.Print.Library/MergedPdf.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using VEPROMS.CSLA.Library;
|
||||
using iTextSharp.text;
|
||||
using iTextSharp.text.pdf;
|
||||
using DescriptiveEnum;
|
||||
using JR.Utils.GUI.Forms;
|
||||
|
||||
namespace Volian.Print.Library
|
||||
{
|
||||
public class MergedPdfProc
|
||||
{
|
||||
private string _Title;
|
||||
public string Title
|
||||
{
|
||||
get { return _Title; } // used for pdf outline
|
||||
set { _Title = value; }
|
||||
}
|
||||
private int _PageCount; // number of pages in the particular pdf, to aid in determining total page count for merged pdf
|
||||
public int PageCount
|
||||
{
|
||||
get { return _PageCount; }
|
||||
set { _PageCount = value; }
|
||||
}
|
||||
private string _PdfFileName; // used for finding the procedure's pdf file to merge
|
||||
public string PdfFileName
|
||||
{
|
||||
get { return _PdfFileName; }
|
||||
set { _PdfFileName = value; }
|
||||
}
|
||||
public MergedPdfProc(string title, string pfname)
|
||||
{
|
||||
_Title = title;
|
||||
_PdfFileName = pfname;
|
||||
}
|
||||
}
|
||||
// this class will manage the data & do subsequent merging of pdf files. It is used if the user
|
||||
// selects the 'Merge' button off of the print dialog when doing a Print All. (C2019-012)
|
||||
public class MergedPdf
|
||||
{
|
||||
private List<MergedPdfProc> _mergedPdfs = null; // This list has all procedure pdfs that will be included in the merged file.
|
||||
public List<MergedPdfProc> MergedPdfs
|
||||
{
|
||||
get { return _mergedPdfs; }
|
||||
set { _mergedPdfs = value; }
|
||||
}
|
||||
string _mergedFileName = null; // this is the name to be given the merged file
|
||||
public string MergedFileName
|
||||
{
|
||||
get { return _mergedFileName; }
|
||||
set { _mergedFileName = value; }
|
||||
}
|
||||
private string _folder; // this is folder to create the merged file in
|
||||
public string Folder
|
||||
{
|
||||
get { return _folder; }
|
||||
set { _folder = value; }
|
||||
}
|
||||
private DocVersionInfo _docVersionInfo;
|
||||
private string _pageof = null;
|
||||
private iTextSharp.text.Font _itextFont = null;
|
||||
private MergedPdfsPageNumCorner _corner;
|
||||
private float _xloc = 0;
|
||||
private float _yloc = 0;
|
||||
// the following constructs the class that contains data for merging a group of pdfs.
|
||||
public MergedPdf(string folder, DocVersionInfo dvi)
|
||||
{
|
||||
_folder = folder;
|
||||
_docVersionInfo = dvi;
|
||||
}
|
||||
// the following merges the procedure pdfs into a single pdf
|
||||
public bool DoTheMerge()
|
||||
{
|
||||
if (MergedPdfs == null)
|
||||
{
|
||||
FlexibleMessageBox.Show("There are no PDFs to merge.", "Merging Pdfs Error", MessageBoxButtons.OK);
|
||||
return false;
|
||||
}
|
||||
iTextSharp.text.Document doc = new iTextSharp.text.Document();
|
||||
string slashReplace = _docVersionInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SlashReplace ?? "_";
|
||||
MergedFileName = _folder + @"\" + _docVersionInfo.MyFolder.Name.Replace("/", slashReplace).Replace("\\", slashReplace) + ".pdf";
|
||||
MergedFileName = ItemInfo.StripRtfFormatting(MergedFileName);
|
||||
PdfWriter writer = null;
|
||||
// see if it can be created and if not, see if it is open and tell user:
|
||||
try
|
||||
{
|
||||
writer = PdfWriter.GetInstance(doc, new FileStream(MergedFileName, FileMode.Create));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Could not create");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(MergedFileName + ".");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("If it is open, close and retry.");
|
||||
FlexibleMessageBox.Show(sb.ToString(), "Error on CreatePdf", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
if (writer == null) return false;
|
||||
doc.Open();
|
||||
PdfContentByte canvas = writer.DirectContent;
|
||||
int mergedPageNumber = 0; // this is the number that will be used for the <page> token (for <page> of <of>)
|
||||
int totalPages = 0; // this is the number that will be used for the <of> token (for <page> of <of>)
|
||||
foreach (MergedPdfProc mpp in MergedPdfs) totalPages += mpp.PageCount;
|
||||
bool doPageNum = GetPageOfInfo(); // get the format and location of page number - this can be reused for each procedure
|
||||
// the MergedPdfs contains a list of all of the procedures' pdfs that will be merged into the final pdf
|
||||
foreach (MergedPdfProc mpp in MergedPdfs)
|
||||
{
|
||||
string pdffilename = _folder + @"\" + mpp.PdfFileName;
|
||||
if (!File.Exists(pdffilename))
|
||||
{
|
||||
FlexibleMessageBox.Show("Error in finding pdf files to merge. Cannot print with date/time as part of pdf name. Or check that individual pdfs were generated.", "Error on CreatePdf", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return false;
|
||||
}
|
||||
PdfReader reader = new PdfReader(_folder + @"\" + mpp.PdfFileName);
|
||||
int numPages = reader.NumberOfPages;
|
||||
int currentPageNumber = 0;
|
||||
PdfOutline outline = null;
|
||||
do // merging pages into complete...
|
||||
{
|
||||
currentPageNumber += 1;
|
||||
mergedPageNumber += 1;
|
||||
doc.SetPageSize(PageSize.LETTER);
|
||||
doc.NewPage();
|
||||
PdfImportedPage page = writer.GetImportedPage(reader, currentPageNumber); // gets a page that is 'ready' to be written to combined pdf
|
||||
if (doPageNum) // get the string & fill in with <page> and <of> numbers
|
||||
{
|
||||
string outputpageof = _pageof.Replace("<page>", mergedPageNumber.ToString()).Replace("<of>", totalPages.ToString());
|
||||
AddPageNumberToPage(page, canvas, outputpageof);
|
||||
}
|
||||
PdfDestination dest = new PdfDestination(PdfDestination.FIT);
|
||||
// if on the first page, add the pdfname & title as part of outline. If on remaining pages, just put out page number.
|
||||
// Later this may need expanded to put sections/steps/etc.
|
||||
if (currentPageNumber == 1)
|
||||
outline = new PdfOutline(canvas.RootOutline, dest, mpp.PdfFileName.Replace(".pdf", "")+" - "+mpp.Title, false);
|
||||
else
|
||||
new PdfOutline(outline, dest, "Page " + currentPageNumber.ToString(), false);
|
||||
canvas.AddTemplate(page, 0, 0); // adds the page to the combined pdf
|
||||
} while (currentPageNumber < numPages);
|
||||
}
|
||||
doc.Close();
|
||||
return true;
|
||||
}
|
||||
// this method adds the page number to the page before it is merged in. It determines the position from the properties
|
||||
// that were set on the doc version properties dialog (these values were set as local class variables from GetPageOfInfo)
|
||||
private void AddPageNumberToPage(PdfImportedPage page, PdfContentByte cb, string outputpage)
|
||||
{
|
||||
float pgright = page.BoundingBox.Right;
|
||||
float pgleft = page.BoundingBox.Left;
|
||||
float pgtop = page.BoundingBox.Top;
|
||||
float pgbot = page.BoundingBox.Bottom;
|
||||
Phrase ph = new Phrase();
|
||||
Chunk chk = new Chunk(outputpage, _itextFont);
|
||||
ph.Add(chk);
|
||||
Paragraph pg = new Paragraph(ph);
|
||||
ColumnText columnText = new ColumnText(cb);
|
||||
switch (_corner)
|
||||
{
|
||||
case MergedPdfsPageNumCorner.TopRight:
|
||||
columnText.Alignment = Element.ALIGN_RIGHT;
|
||||
columnText.SetSimpleColumn(0, pgtop - _yloc, pgright - _xloc, 0);
|
||||
break;
|
||||
case MergedPdfsPageNumCorner.BottomRight:
|
||||
columnText.Alignment = Element.ALIGN_RIGHT;
|
||||
columnText.SetSimpleColumn(0, _yloc, pgright - _xloc, 0);
|
||||
break;
|
||||
case MergedPdfsPageNumCorner.TopLeft:
|
||||
columnText.SetSimpleColumn(_xloc, pgtop - _yloc, pgright, 0); // page alignment defaults to ALIGN_LEFT
|
||||
break;
|
||||
case MergedPdfsPageNumCorner.BottomLeft:
|
||||
columnText.SetSimpleColumn(_xloc, _yloc, pgright, 0); // page alignment defaults to ALIGN_LEFT
|
||||
break;
|
||||
}
|
||||
columnText.AddText(pg);
|
||||
columnText.Go();
|
||||
}
|
||||
// this method gets the format, font & location data from the doc version properties that are stored on the doc version's
|
||||
// config field. It saves them as local class variables to be used in other places in this class.
|
||||
private bool GetPageOfInfo()
|
||||
{
|
||||
DocVersionConfig dvc = (DocVersionConfig) _docVersionInfo.MyConfig;
|
||||
MergedPdfsPageOf po = dvc.Print_MergedPdfsPageOf;
|
||||
string tmp = EnumDescConverter.GetEnumDescription((Enum)dvc.Print_MergedPdfsPageOf);
|
||||
if (tmp == "None") return false; // no page number, return false so no page number is put out.
|
||||
|
||||
// If 'Other' for the format, use text in textbox to format the <page> of <of> string, note that <page> and <of> are
|
||||
// resolved when adding pages to the merge document. The only other 'token' that is supported is '<set>'
|
||||
if (tmp == "Other") tmp = dvc.Print_MergedPdfsPageNumFormatOther;
|
||||
_pageof = tmp.Replace("<set>", _docVersionInfo.MyFolder.Name);
|
||||
|
||||
// If font data is not supplied, use the default from the format for this working draft
|
||||
string famtmp = dvc.Print_MergedPdfsPageNumFont;
|
||||
if (famtmp == null || famtmp == "")
|
||||
{
|
||||
famtmp = _docVersionInfo.ActiveFormat.PlantFormat.FormatData.Font.Family;
|
||||
}
|
||||
tmp = dvc.Print_MergedPdfsPageNumFontSize;
|
||||
float? tmpi=0;
|
||||
if (tmp == null || tmp == "")
|
||||
{
|
||||
// use the default from the format from this working draft
|
||||
tmpi = _docVersionInfo.ActiveFormat.PlantFormat.FormatData.Font.Size;
|
||||
}
|
||||
else
|
||||
tmpi = int.Parse(tmp);
|
||||
|
||||
// set local values of variables to be used in various other methods in this class.
|
||||
_itextFont = Volian.Svg.Library.Svg.GetFont(famtmp, (float)tmpi, 0, System.Drawing.Color.Black);
|
||||
_xloc = (float)dvc.Print_MergedPdfsPageNumLocX * 72;
|
||||
_yloc = (float)dvc.Print_MergedPdfsPageNumLocY * 72;
|
||||
_corner = dvc.Print_MergedPdfsPageNumCorner;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -259,9 +259,22 @@ namespace Volian.Print.Library
|
||||
get { return _BlankPageText; }
|
||||
set { _BlankPageText = value; }
|
||||
}
|
||||
|
||||
// use DidAll & MergeNotIncuded to know that printing all (not single) was done. Used w/ merge code to know when to return, i.e. not include in merged pdf
|
||||
private bool _DidAll;
|
||||
public bool DidAll // value passed in from frmPdfStatusForm
|
||||
{
|
||||
get { return _DidAll; }
|
||||
set { _DidAll = value; }
|
||||
}
|
||||
private bool _MergeNotIncluded;
|
||||
public bool MergeNotIncluded
|
||||
{
|
||||
get { return _MergeNotIncluded; }
|
||||
set { _MergeNotIncluded = value; }
|
||||
}
|
||||
|
||||
public PromsPrinter(ItemInfo myItem, string rev, string watermark, bool debugOutput, bool origPgBrk, string backgroundFolder, bool openPDF, bool overWrite,
|
||||
ChangeBarDefinition cbd, String pdfFile, bool insertBlankPages, bool batchPrint, string prefix, bool saveLinks, bool removeTrailngHardReturnsAndManualPageBreaks, string blankPageText)
|
||||
ChangeBarDefinition cbd, String pdfFile, bool insertBlankPages, bool batchPrint, string prefix, bool saveLinks, bool removeTrailngHardReturnsAndManualPageBreaks, string blankPageText, bool didAll)
|
||||
{
|
||||
Prefix = prefix; // RHM20150506 Multiline ItemID TextBox
|
||||
_MyItem = myItem;
|
||||
@@ -280,6 +293,8 @@ namespace Volian.Print.Library
|
||||
_SaveLinks = saveLinks;
|
||||
_RemoveTrailingHardReturnsAndManualPageBreaks = removeTrailngHardReturnsAndManualPageBreaks;
|
||||
_BlankPageText = blankPageText;
|
||||
_DidAll = didAll;
|
||||
_MergeNotIncluded = false;
|
||||
//_MyReaderHelper.LoadTree(myItem);
|
||||
}
|
||||
// Pass 1 PDF Name
|
||||
@@ -299,7 +314,14 @@ namespace Volian.Print.Library
|
||||
public string Print(string pdfFolder, bool makePlacekeeper, bool makeContinuousActionSummary)
|
||||
{
|
||||
if (_MyItem is ProcedureInfo)
|
||||
{ // B2017-186 First do Procedures that don't have page number transitions
|
||||
{
|
||||
ProcedureConfig pcfg = (ProcedureConfig)(_MyItem as ProcedureInfo).MyConfig;
|
||||
if (DidAll && pcfg.Print_NotInMergeAll) // will be merging a pdf, so don't print this procedure if user set that on procedure propertures
|
||||
{
|
||||
_MergeNotIncluded = true;
|
||||
return null;
|
||||
}
|
||||
// B2017-186 First do Procedures that don't have page number transitions
|
||||
if (!(_MyItem.ActiveFormat.PlantFormat.FormatData.TransData.UseTransitionModifier ||
|
||||
_MyItem.ActiveFormat.PlantFormat.FormatData.TransData.UseSpecificTransitionModifier))
|
||||
{
|
||||
@@ -446,11 +468,13 @@ namespace Volian.Print.Library
|
||||
_PROMSVersionLayer.SetPrint("PROMS Version", true);
|
||||
}
|
||||
}
|
||||
public static int ProcPageCount = -1; // Used to count page numbers in each pdf. This will be used if/when pdfs are merged together.
|
||||
private void CloseDocument(string fileName)
|
||||
{
|
||||
int profileDepth = ProfileTimer.Push(">>>> CloseDocument");
|
||||
try
|
||||
{
|
||||
ProcPageCount = MyContentByte.PdfWriter.CurrentPageNumber - 1;
|
||||
MyContentByte.PdfDocument.Close();
|
||||
MyContentByte = null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user