How can I reduce the top margin of a MigraDoc document? - migradoc

How can I reduce the top margin of a MigraDoc document?
I added an image to the top right of my document however the space between the top of the document and the image is too big.
Here is how I'm setting the image:
Section section = document.AddSection();
Image image = section.AddImage(#"C:\img\mentSmallLogo.png");
image.Height = "1.5cm";
image.Width = "4cm";
image.LockAspectRatio = true;
image.RelativeVertical = RelativeVertical.Line;
image.RelativeHorizontal = RelativeHorizontal.Margin;
image.Top = ShapePosition.Top;
image.Left = ShapePosition.Right;
image.WrapFormat.Style = WrapStyle.Through;
And the document style:
Style style = document.Styles["Normal"];
style.Font.Name = "Verdana";
style = document.Styles[StyleNames.Header];
style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right);
style = document.Styles[StyleNames.Footer];
style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center);
// Create a new style called Table based on style Normal
style = document.Styles.AddStyle("Table", "Normal");
style.Font.Name = "Verdana";
style.Font.Name = "Times New Roman";
style.Font.Size = 8;
// Create a new style called Reference based on style Normal
style = document.Styles.AddStyle("Reference", "Normal");
style.ParagraphFormat.SpaceBefore = "5mm";
style.ParagraphFormat.SpaceAfter = "5mm";
style.ParagraphFormat.TabStops.AddTabStop("16cm", TabAlignment.Right);
style.ParagraphFormat.Font.Size = 8;
How can I reduce the space between the image and the top of the page?

Set image.WrapFormat.DistanceTop to set the top position of the image.
If you set the image position this way, there is no need to modify the PageSetup.
There are different values for RelativeVertical that can be used. And you can also use negative values.
See also:
http://forum.pdfsharp.net/viewtopic.php?p=5267#p5267
With respect to the other answer: it is good practice not to modify DefaultPageSetup. Instead make a Clone() of DefaultPageSetup and modify that.
The PageSetup of your documentis specific to your document. The DefaultPageSetup is shared by all documents; modifying it can lead to strange effects when you persist documents in MDDDL format or when your application has different documents with different page setups.
Code that creates a clone can look like this:
var doc = new Document();
var section = doc.AddSection();
section.PageSetup = doc.DefaultPageSetup.Clone();
Then you can make all necessary changes to section.PageSetup. If you need different settings for other sections, you can use either doc.DefaultPageSetup.Clone() or section.PageSetup.Clone() to get started.

something like this
document.DefaultPageSetup.LeftMargin = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(.8);
document.DefaultPageSetup.TopMargin = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(.5);
document.DefaultPageSetup.PageWidth = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(11);

My solution to this involved having the image in my header section of the document, and controlling the position within the header by enclosing it in a borderless table.
Actual header and footer sections of the document are not effected by the margins applied to the document, they have their own Unit properties.
There is a HeaderDistance property in the PageSetup object of the document.
Same thing exists for Footers (FooterDistance).
https://forum.pdfsharp.net/viewtopic.php?f=2&t=3076
document.DefaultPageSetup.HeaderDistance = "0.20in";
document.DefaultPageSetup.FooterDistance = "0.20in";
Although other answers say to not modify DefaultPageSetup directly, it is a read-only variable in the document object, so you cannot set it equal to a clone. This is the best way.

Related

Header in a XWPFDocument is only on the last page when adding section breaks

I am trying to create a word document using Apache POI. This document includes images, and I need to flip the page with the image to be landscape oriented, while keeping the rest of the document portrait oriented. However, I also need to use a header (and a footer, but I assume it is gonna work the same way as headers do).
The code I am using:
val document = XWPFDocument()
// the header I need to be on every page
document.createHeader(HeaderFooterType.DEFAULT).createParagraph().createRun().setText("Header")
// some text before the image
var par = document.createParagraph()
var run = par.createRun()
run.setText("I am text")
// add the image, flip the page with the image onto landscape
par = document.createParagraph()
val pageSize = par.ctp.addNewPPr().addNewSectPr().addNewPgSz() // this creates new section, so I can get the pageSize
pageSize.orient = STPageOrientation.LANDSCAPE
pageSize.h = BigInteger.valueOf(595 * 20) // unit used TWIPS (Twentieth of an Imperial Point)
pageSize.w = BigInteger.valueOf(842 * 20)
run = par.createRun()
val decodedByteArray = Base64.getDecoder().decode(PLACEHOLDER_IMAGE.substringAfter(','))
run.addPicture(
ByteArrayInputStream(decodedByteArray),
XWPFDocument.PICTURE_TYPE_PNG,
"",
pixelToEMU(400),
pixelToEMU(150)
)
// some text after the image
par = document.createParagraph()
run = par.createRun()
run.setText("Me too")
val out = FileOutputStream("Output.docx")
document.write(out)
out.close()
document.close()
The resulting document however has the header only after the last section break. I am aware, that every section has its' own header/footer, and that you can set the header to be the same as the previous, but the header I need seems to be always the last header, and I have no idea how to make it stick to the front of the document, where it can be used by the following sections.
Image of the resulting document
So my question is: How can I make the header appear on every page, while keeping the page formatting as is? If there is a way to make the individual pages, with the images, flip orientation without inserting section breaks, that would be a solution aswell.
In my attempts to solve this, I've been able to put data only into the header in the last section, but never have I managed to actually get my hands on the headers in the previous sections, or on the default header. Notice, that the header in the code I'm creating is set as default, but the real default header is empty and I haven't been able to access it.
NOTE: This is not the actual project, here I've only isolated the problem into a much simpler code without giving any real thought to coding style, etc.
The problem is that sections not only have separate page settings but have separate header/footer settings too.
XWPFDocumnet.createHeader creates a header which reference gets stored in document body section properties. If you create a paragraph having own section properties - a section break paragraph - then the section properties in this section break paragraph also needs a reference to a header, else the section above that section break paragraph has no header.
Best solution I can think of is to always take a copy of the document body section properties to be the section properties of additional section break paragraphs. Then only change what needs to be changed. So the copy contains needed references to headers and/or footeres already.
The following complete example shows that. The method createSectionbreak always takes a copy of the document body section properties, except there are none. Then it creates new section properties for the section break paragraph. The method setPageSizeLandscape then changes the page size.
The code is Java code. Me not using Kotlin. But the principle shold be clear also from that.
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
public class CreateWordSectionsPageSizeHeader {
static org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr getDocumentBodySectPr(XWPFDocument document) {
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1 ctDocument = document.getDocument();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody ctBody = ctDocument.getBody();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr ctSectPrDocumentBody = ctBody.getSectPr();
return ctSectPrDocumentBody;
}
static XWPFParagraph createSectionbreak(XWPFDocument document) {
XWPFParagraph sectionBreakParagraph = document.createParagraph();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr ctSectPrDocumentBody = getDocumentBodySectPr(document);
if (ctSectPrDocumentBody != null) {
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr ctSectPrNewSect = (org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr)ctSectPrDocumentBody.copy();
sectionBreakParagraph.getCTP().addNewPPr().setSectPr(ctSectPrNewSect);
} else {
sectionBreakParagraph.getCTP().addNewPPr().addNewSectPr();
}
return sectionBreakParagraph;
}
static void setPageSizeLandscape(XWPFParagraph sectionBreakParagraph) {
if (sectionBreakParagraph.getCTP().getPPr() == null) return;
if (sectionBreakParagraph.getCTP().getPPr().getSectPr() == null) return;
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr ctSectPr = sectionBreakParagraph.getCTP().getPPr().getSectPr();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz ctPageSz = ctSectPr.getPgSz();
if (ctPageSz == null) ctPageSz = ctSectPr.addNewPgSz();
ctPageSz.setOrient​(org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation.LANDSCAPE);
// paper format letter
ctPageSz.setH(java.math.BigInteger.valueOf(12240)); //12240 Twips = 12240/20 = 612 pt = 612/72 = 8.5"
ctPageSz.setW(java.math.BigInteger.valueOf(15840)); //15840 Twips = 15840/20 = 792 pt = 792/72 = 11"
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph;
XWPFRun run;
// create header start
XWPFHeader header = document.createHeader(HeaderFooterType.DEFAULT);
paragraph = header.getParagraphArray(0);
if (paragraph == null) paragraph = header.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
run = paragraph.createRun();
run.setText("Header");
// create header end
// create body content
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Text in section 1");
// create section break
paragraph = createSectionbreak(document);
setPageSizeLandscape(paragraph);
// create section break end
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Text in section 2");
// create body content end
FileOutputStream out = new FileOutputStream("./CreateWordSectionsPageSizeHeader.docx");
document.write(out);
out.close();
document.close();
}
}

How can I display a logo and its description in the same line using iTextSharp?

I want to show a logo and its description in a pdf using itextSharp.
Example:
Logo LogoDescription
My below code shows logo and its description on two different lines
Document^ doc = gcnew Document(iTextSharp::text::PageSize::LETTER,10,10,42,32);
doc->Open();
// add image
iTextSharp::text::Image^ bmp = iTextSharp::text::Image::GetInstance("bts_logo.bmp");
bmp->ScaleToFit(50,100);
bmp->Border = iTextSharp::text::Rectangle::BOX;
bmp->BorderColor = iTextSharp::text::BaseColor::RED;
bmp->BorderWidth = 2;
doc->Add(bmp);
doc->Add(gcnew Phrase("Logo description", gcnew iTextSharp::text::Font(iTextSharp::text::Font::FontFamily::HELVETICA, 11, iTextSharp::text::Font::BOLD)));
I am using Visual Studio 2012.
If you want to add a Phrase (e.g. a description) next to an Image (e.g. a picture), you typically create a PdfPTable:
PdfPTable table^ = gcnew PdfpTable(2);
This will create a table that shows borders by default. You can change this by adding this line:
table->DefaultCell->Border = iTextSharp::text::Rectangle::NO_BORDER;
You then add the image and the text as cells:
table->AddCell(bmp);
table->AddCell(phrase);
Where bmp is an instance of the Image class, and phrase is an instance of the Phrase class.
You then add the table to the document:
doc->Add(table);
The table will have borders by default, but as I am not familiar with the programming language you are using, you probably know better how to change the border of the default cell to NO_BORDER than I do.

Add a footer to an exported OxyPlot plot

I am using OxyPlot to export plots.
When I export them, I want to add a footer to these plots with information like the path it is saved, a time-stamp, and so on...
Right now I am doing this by creating an extra X-axis on a different position-tier and then setting the sizes of all ticks and labels to zero except for the title font-size.
This works, but as you might imagine, this is quite hacky and does not look that good (as you cannot set for example the aligning).
So my question is, is there a possibility to add such a footer to the exported plot?
EDIT:
var xAxis = new OxyPlot.Axes.LinearAxis
{
Position = AxisPosition.Bottom,
PositionTier = 1,
Title = "Footer: i.e. path to my file",
MinorTickSize = 0.0,
MajorTickSize = 0.0,
FontSize = 0.0,
TitleFontSize = 12,
AxisDistance = 10
};
This is the workaround I mentioned.
I create an axis at position-tier 1, which is below the first one and then disable all visuals of it except the title.
And in the end I add it to my plotmodel pm.Axes.Add(xAxis).
To export my plotmodel I use PdfExporter like this:
using (var stream = File.Create(testFile.pdf))
{
PdfExporter.Export(pm, stream, 800, 500);
}
Greetings
Chriz
Just had to do the same thing with my project and thought I'd share how I managed it for anyone else in need of a footer.
I couldn't find any built in OxyPlot methods to add a header or footer but if you use OxyPlot.PDF it's built on top of PDFSharp and you have more options to customize your PDF export.
Remove any previous reference to OxyPlot.Pdf in your project.
Download OxyPlot.Pdf source code from: https://github.com/oxyplot/oxyplot
In your project in VS, right click your solution in 'Solution Explorer' and Add Existing Project.
Navigate to the downloaded source code and add OxyPlot.Pdf.csproj
Right click your project and Add Reference
Select 'Projects' on the left and check the box for OxyPlot.Pdf on the right. Hit OK.
Check that it's working by building and running project.
Go to PdfRenderContext.cs file and find the PdfRenderContext method near the top.
Add the code below then build and run your project.
This code creates a MigraDoc Document and then merges it with the OxyPlot PdfDocument.
public PdfRenderContext(double width, double height, OxyColor background)
{
//*** Original Code - Don't change **//
this.RendersToScreen = false;
this.doc = new PdfDocument();
var page = new PdfPage { Width = new XUnit(width), Height = new XUnit(height) };
this.doc.AddPage(page);
this.g = XGraphics.FromPdfPage(page);
if (background.IsVisible())
{
this.g.DrawRectangle(ToBrush(background), 0, 0, width, height);
}
//*** New Code to add footer **//
Document myDoc = new Document();
Section mySection = myDoc.AddSection();
Paragraph footerParagraph = mySection.Footers.Primary.AddParagraph();
footerParagraph.AddText(DateTime.Now.ToShortDateString());
footerParagraph.Format.Alignment = ParagraphAlignment.Right;
MigraDoc.Rendering.DocumentRenderer docRenderer = new MigraDoc.Rendering.DocumentRenderer(myDoc);
docRenderer.PrepareDocument();
docRenderer.RenderObject(g, XUnit.FromInch(9.5), XUnit.FromInch(8), "1in", footerParagraph);
}
When you export the PDF a date stamp is now added to the lower right corner of the PDF. Note that I was working with landscape 8.5x11 inch paper so you may need to change position if you don't see it on the plot. Upper left corner is 0,0. Once it's working, build the OxyPlot.Pdf project to create the dll and then you can add it as a reference to your project and remove the source code.
Result:

InDesign CS6 scripting - Add overflowing content on next page(s)

After I imported XML-Data into an InDesign document I see that red plus symbol at the textframe at the end of the first page.
How can I insert/move that content on next page(s) with scripting?
This script should do what you want. :)
var myDoc = app.activeDocument;
var myFrames = myDoc.textFrames;
while (myFrames[0].overflows === true) {
var myNewPage = myDoc.pages.add();
var myMargin = myNewPage.marginPreferences;
var myBounds = [myMargin.top, myMargin.left, myDoc.documentPreferences.pageHeight - myMargin.bottom, myDoc.documentPreferences.pageWidth - myMargin.right];
var myOldRuler = myDoc.viewPreferences.rulerOrigin;
myDoc.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin;
with(myDoc.pages[-1].textFrames.add()) {
geometricBounds = myBounds;
previousTextFrame = myDoc.pages[-2].textFrames[0];
}
myDoc.viewPreferences.rulerOrigin = myOldRuler;
}
The TextFrame object has a property overflows: Bool, readonly. If true, the story has overset text.
The TextFrame object has also a property nextTextFrame: r/w The next text frame in the thread. Can return: TextFrame or TextPath. Can also accept: NothingEnum enumerator.
http://jongware.mit.edu/idcs6js/pc_TextFrame.html
not sure you need scripting... if the document is set up as a template simply click the plus sign and "capture" the contents. then move to the next page and click where you want the text to reflow to. adjust the text boxes as needed to suit.
For the non-scripting solution to flowing overset text frames, after adding a new page, hold down shift before clicking. This will cause the text to autoflow on as many pages as it takes until there is no longer an overset text frame.
From CS4, we can enable the "Smart Text Reflow" to automatically flow text to the available content. It will insert the pages automatically.
Edit Menu \ Preferences \ Type \ Smart Text Reflow
Also, it comes with "Delete Empty Pages", so when the content goes less, then it will automatically remove the empty pages accordingly.

Cannot set individual icon heading using SharpKML

Using SharpKML library from VB (VS2010), I can create kml files with a custom icon for each placemark. The placemarks are created in a loop and I want to set the icon's heading property for each placemark.
'Define the style for the icon
Dim kmlStyle As New SharpKml.Dom.Style
kmlStyle.Id = "ShipIcon"
kmlStyle.Icon = New SharpKml.Dom.IconStyle
kmlStyle.Icon.Icon = New SharpKml.Dom.IconStyle.IconLink(New System.Uri("http://www.mysite.com/mapfiles/ship4.png"))
kmlStyle.Icon.Scale = 1
Poscommand.CommandText = "SELECT * FROM Ships"
PosReader = Poscommand.ExecuteReader()
While PosReader.Read()
'Add placemark for position
kmlPosPoint = New SharpKml.Dom.Point
kmlPosPoint.Coordinate = New SharpKml.Base.Vector(PosReader("Lat"), PosReader("Lon"))
kmlPosPlaceMark = New SharpKml.Dom.Placemark
kmlPosPlaceMark.Geometry = kmlPosPoint
kmlPosPlaceMark.Name = "My Name"
kmlPosPlaceMark.StyleUrl = New System.Uri("#ShipIcon", UriKind.Relative)
'SET icon.heading HERE??? How to access icon heading property for this placemark only???
End While
Can anybody help me set the icon heading for an individual placemark using SharpKML?
The Heading is actually a property of IconStyle and not Icon (Icon is a child property of IconStyle and only specifies the URL to the icon image.
In your code above it would be (from memory):
kmlStyle.Icon.Heading = 90;
Because you are using a common style for all items I believe you can override just parts of a Style like this inside your loop (please post the result if you test):
kmlPosPlaceMark.StyleUrl = New System.Uri("#ShipIcon", UriKind.Relative);
Style s = new Style();
s.Icon = new IconStyle();
s.Icon.Heading = 90;
kmlPosPlaceMark.StyleSelector = s;
If that doesn't work you might have to create and set a style per Placemark, but i am pretty sure that is not the case. Again, please post back and let us know how you make out.