问题
I use the following routine to export (save) a chartsheet as pdf. The function gets the names of the user selected chartsheets in a collection. Then it exports one by one as a pdf where the user can select the save folder of the exported pdf. Here my code.
Private Function ExportCurvesPDF(Curves As Collection)
Dim source As Workbook
Dim i As Integer
Dim FileName As String
Dim ExportPath As String
Set source = Thisworkbook
ExportPath = "V:\"
For i = 1 To Curves.count
FileName = Application.GetSaveAsFilename(ExportPath & Curves(i) & ".pdf")
If FileName <> "False" Then
source.Sheets(Curves(i)).ExportAsFixedFormat Type:=xlTypePDF, FileName:=FileName, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
End If
ExportPath = common_DB.FolderFromPath(FileName)
Next i
End Function
The code works as expected and prints out the pdfs as an example below:
The pdf has quite the margin though and I want to reduce or remove it. I have tried to change the IgnorePrintArea
property and the IncludeDocProperties
property but nothing seems to have an effect on the margin.
Is there a way to reduce the margin with the .ExportAsFixedFileFormat
?
EDIT: I was asked to provide a screenshot of how the chart looks in excel:
回答1:
You could try and specify a bit more the area to export. This will work if the .pdf
content has been reduced. For instance, lets say your chart is align with the cells A1
to H30
. You could export:
source.Sheets(Curves(i)).Range("A1:H30").ExportAsFixedFormat Type:=xlTypePDF...
Remember you could list your ranges to fit this in your own code.
By doing this, you can avoid the extra red line on the top of your document.
回答2:
May be I failed to understand the question clearly. If you only want to reduce margin, then it seems too simple for a bounty question (just reduce margins to 0 or required in PageSetup
). result may be like this
With source.Sheets(Curves(i)).PageSetup
.LeftMargin = Application.InchesToPoints(0)
.RightMargin = Application.InchesToPoints(0)
.TopMargin = Application.InchesToPoints(0)
.BottomMargin = Application.InchesToPoints(0)
.HeaderMargin = Application.InchesToPoints(0)
.FooterMargin = Application.InchesToPoints(0)
End With
source.Sheets(Curves(i)).ExportAsFixedFormat Type:=xlTypePDF, FileName:=FileName, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
回答3:
The code below worked for me.
I left some commented lines which might be useful for you.
I am not sure ch.Activate
is needed. I would expect it is not, but I did not test it thoroughly.
The image I obtained is below as well. I don't know if that is too much of a margin for you, but it seems to have less white margin than your case.
' Sub only for testing
Private Sub ExportCurvesPDF_caller()
Dim chsheets As Sheets
Set chsheets = Charts
Call ExportCurvesPDF(chsheets)
End Sub
' The Subs you need
Private Sub ExportCurvesPDF(Curves As Sheets)
Dim ExportPath As String
ExportPath = "C:\Users\user1\Documents\"
Dim ch As Chart
For Each ch In Curves
Dim FileName As String
FileName = ExportPath & ch.Name
ch.Activate
Call set_margins(ch)
ch.ExportAsFixedFormat Type:=xlTypePDF, FileName:=FileName, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
Next ch
End Sub
Private Sub set_margins(ch As Chart)
Application.PrintCommunication = False
With ch.PageSetup
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0)
.RightMargin = Application.InchesToPoints(0)
.TopMargin = Application.InchesToPoints(0)
.BottomMargin = Application.InchesToPoints(0)
.HeaderMargin = Application.InchesToPoints(0)
.FooterMargin = Application.InchesToPoints(0)
'.ChartSize = xlScreenSize
'.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
'.Orientation = xlLandscape
.Draft = False
.OddAndEvenPagesHeaderFooter = False
'.DifferentFirstPageHeaderFooter = False
'.EvenPage.LeftHeader.Text = ""
'.EvenPage.CenterHeader.Text = ""
'.EvenPage.RightHeader.Text = ""
'.EvenPage.LeftFooter.Text = ""
'.EvenPage.CenterFooter.Text = ""
'.EvenPage.RightFooter.Text = ""
'.FirstPage.LeftHeader.Text = ""
'.FirstPage.CenterHeader.Text = ""
'.FirstPage.RightHeader.Text = ""
'.FirstPage.LeftFooter.Text = ""
'.FirstPage.CenterFooter.Text = ""
'.FirstPage.RightFooter.Text = ""
.PaperSize = xlPaperA4
'.FirstPageNumber = xlAutomatic
'.BlackAndWhite = False
'.Zoom = 100
End With
Application.PrintCommunication = True
End Sub
回答4:
Solution using Word as a helper application
As far as I know, there is no way by just using .ExportAsFixedFileFormat
but what you desire is possible using Word as a helper application, as I will demonstrate in the following code.
To make exporting a bunch of charts not constantly open and close Word I implemented a ShapeExporter
Class, that holds an instance of Word and uses it for exporting the charts or shapes:
Usage in a normal module, if the charge is an embedded chart (chart in a worksheet)
Sub ExportChartToPDF()
' Setting up the variables for passing to ShapeExporter
Dim MyChart As Object
' If your chart is an embedded chart in a worksheet
Set MyChart = ThisWorkbook.Worksheets("YourWorksheet").ChartObjects("ChartName")
' If your chart is it's own "chart sheet" like in os's question:
Set MyChart = ThisWorkbook.Charts("ChartSheetName").ChartArea
Dim fileName As String
fileName = "TestExport"
Dim filePath As String
filePath = ThisWorkbook.Path
' Creating an instance of our ShapeExporter:
' During the creation of the object, Word is opened in the background
' if it wasn't already open.
Dim oShapeExporter As cShapeExporter
Set oShapeExporter = New cShapeExporter
' Export as many shapes as you want here, before destroying oShapeExporter
' The ExportShapeAsPDF method pastes the chart in a word document, resizes the
' Document to be exactly the size of the chart and then saves it as PDF
oShapeExporter.ExportShapeAsPDF MyChart, fileName, filePath
' As the object goes out of scope, the background instance of Word
' gets closed, if it wasn't open at the time of the creation of the object
Set oShapeExporter = Nothing
End Sub
To use the exporter object you have to paste the following code to a class module and name the class module cShapeExporter
:
Option Explicit
' Storing the instance of Word in the object
Dim wdApp As Object
Dim wdDoc As Object
Dim wdWasOpen As Boolean
Private Sub Class_Initialize()
' Opening Word
If WordIsRunning Then
Set wdApp = GetObject(, "Word.Application")
wdWasOpen = True
Else
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = False
wdWasOpen = False
End If
' And creating a Document that will be used for the pasting and exporting
Set wdDoc = wdApp.Documents.Add
' Setting margins to 0 so we have no white borders!
' If you want, you can set custom white borders for the exported PDF here
With wdDoc.PageSetup
.LeftMargin = 0
.RightMargin = 0
.TopMargin = 0
.BottomMargin = 0
End With
End Sub
Private Sub Class_Terminate()
' Important: Close Word as the object is destroyed, but only if it wasn't
' previously opened!
If Not wdWasOpen Then
wdApp.Quit 0 '(wdDoNotSaveChanges)
Else
wdDoc.Close 0
End If
Set wdApp = Nothing
Set wdDoc = Nothing
End Sub
Public Sub ExportShapeAsPDF(xlShp As Object, fileName As String, filePath As String)
' Defining which objects can be exported, maybe others are also supported,
' they just need to support all the methods and have all the properties used
' in this sub
If TypeName(xlShp) = "ChartObject" Or TypeName(xlShp) = "Shape" Or TypeName(xlShp) = "ChartArea" Then
'fine
Else
MsgBox "Exporting Objects of type " & TypeName(xlShp) & " not supported, sorry."
Exit Sub
End If
' Copying the Excel object into the Word Document
xlShp.Copy
wdDoc.Range.Paste
Dim wdShp As Object
Set wdShp = wdDoc.Shapes(1)
' Resizing the Word Document
With wdDoc.PageSetup
.PageWidth = wdShp.Width
.PageHeight = wdShp.Height
End With
' Aligning the pasted object
wdShp.Top = 0
wdShp.Left = 0
' Export as .pdf
wdDoc.saveas2 fileName:=filePath & "\" & fileName, FileFormat:=17 '(wdExportFormatPDF)
' Delete shape in wdDoc
wdShp.Delete
End Sub
' Utility Function
Private Function WordIsRunning() As Boolean
Dim wdApp As Object
On Error Resume Next
Err.Clear
Set wdApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
WordIsRunning = False
Else
WordIsRunning = True
End If
End Function
来源:https://stackoverflow.com/questions/53886601/print-chartsheet-without-margin-from-excel-using-vbas-exportasfixedformat-meth