hi,
i tried the code from a blog, but i get an error at the line
pe.BeginPage(ppi, pi, (numSheet == layoutsToPlot.Count), null);
the first layouts is okay, but at the following layouts there occurs the error eInvalidPlotInfo.
what is wrong there?
[CommandMethod("mplot")]
static public void MultiSheetPlot()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
PlotInfo pi = new PlotInfo();
PlotInfoValidator piv =
new PlotInfoValidator();
piv.MediaMatchingPolicy =
MatchingPolicy.MatchEnabled;
// A PlotEngine does the actual plotting
// (can also create one for Preview)
if (PlotFactory.ProcessPlotState ==
ProcessPlotState.NotPlotting)
{
PlotEngine pe =
PlotFactory.CreatePublishEngine();
using(pe)
{
// Collect all the paperspace layouts
// for plotting
ObjectIdCollection layoutsToPlot =
new ObjectIdCollection();
foreach (ObjectId btrId in bt)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
btrId,
OpenMode.ForRead
);
if (btr.IsLayout &&
btr.Name.ToUpper() !=
BlockTableRecord.ModelSpace.ToUpper())
{
layoutsToPlot.Add(btrId);
}
}
int numSheet = 1;
// Create a Progress Dialog to provide info
// and allow thej user to cancel
PlotProgressDialog ppd =
new PlotProgressDialog(
false,
layoutsToPlot.Count,
true
);
using (ppd)
{
foreach (ObjectId btrId in layoutsToPlot)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
btrId,
OpenMode.ForRead
);
Layout lo =
(Layout)tr.GetObject(
btr.LayoutId,
OpenMode.ForRead
);
// We need a PlotSettings object
// based on the layout settings
// which we then customize
PlotSettings ps =
new PlotSettings(lo.ModelType);
ps.CopyFrom(lo);
// The PlotSettingsValidator helps
// create a valid PlotSettings object
PlotSettingsValidator psv =
PlotSettingsValidator.Current;
// We'll plot the extents, centered and
// scaled to fit
psv.SetPlotType(
ps,
Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
);
psv.SetUseStandardScale(ps, true);
psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
psv.SetPlotCentered(ps, true);
// We'll use the standard DWFx PC3, as
// this supports multiple sheets
psv.SetPlotConfigurationName(ps, lo.PlotConfigurationName, lo.CanonicalMediaName);
// We need a PlotInfo object
// linked to the layout
pi.Layout = btr.LayoutId;
// Make the layout we're plotting current
LayoutManager.Current.CurrentLayout =
lo.LayoutName;
// We need to link the PlotInfo to the
// PlotSettings and then validate it
pi.OverrideSettings = ps;
piv.Validate(pi);
if (numSheet == 1)
{
ppd.set_PlotMsgString(
PlotMessageIndex.DialogTitle,
"Custom Plot Progress"
);
ppd.set_PlotMsgString(
PlotMessageIndex.CancelJobButtonMessage,
"Cancel Job"
);
ppd.set_PlotMsgString(
PlotMessageIndex.CancelSheetButtonMessage,
"Cancel Sheet"
);
ppd.set_PlotMsgString(
PlotMessageIndex.SheetSetProgressCaption,
"Sheet Set Progress"
);
ppd.set_PlotMsgString(
PlotMessageIndex.SheetProgressCaption,
"Sheet Progress"
);
ppd.LowerPlotProgressRange = 0;
ppd.UpperPlotProgressRange = 100;
ppd.PlotProgressPos = 0;
// Let's start the plot, at last
ppd.OnBeginPlot();
ppd.IsVisible = true;
pe.BeginPlot(ppd, null);
// We'll be plotting a single document
pe.BeginDocument(
pi,
doc.Name,
null,
1,
true, // Let's plot to file
"c:\\test-multi-sheet"
);
}
// Which may contain multiple sheets
ppd.StatusMsgString =
"Plotting " +
doc.Name.Substring(
doc.Name.LastIndexOf("\\") + 1
) +
" - sheet " + numSheet.ToString() +
" of " + layoutsToPlot.Count.ToString();
ppd.OnBeginSheet();
ppd.LowerSheetProgressRange = 0;
ppd.UpperSheetProgressRange = 100;
ppd.SheetProgressPos = 0;
PlotPageInfo ppi = new PlotPageInfo();
pe.BeginPage(
ppi,
pi,
(numSheet == layoutsToPlot.Count),
null
);
pe.BeginGenerateGraphics(null);
ppd.SheetProgressPos = 50;
pe.EndGenerateGraphics(null);
// Finish the sheet
pe.EndPage(null);
ppd.SheetProgressPos = 100;
ppd.OnEndSheet();
numSheet++;
}
// Finish the document
pe.EndDocument(null);
// And finish the plot
ppd.PlotProgressPos = 100;
ppd.OnEndPlot();
pe.EndPlot(null);
}
}
}
else
{
ed.WriteMessage(
"\nAnother plot is in progress."
);
}
}
}
}
}
Hi
Some of the reasons might be 1/ that when using this approach each layout needs to have the same paper size 2/ the layouts need to be fully initialized before plotting, which means they need to be opened visible at least once in AutoCAD.
I hope it helps.
Philippe Leefsma
Developer Consultant
Developer Technical Services
Global Subscription & Support
Autodesk EMEA
Hi.
I have also the same problem.If i set the same paper size all works fine ,but if i need different paper size don't work.
I have try with the command PUBLISH and here works also with different paper size.do you have solve it?
thanks
The reply from @philippe.leefsma has already explicitly stated that this code of printing multiple sheets only works when all layouts' sheet size are the same.
So, if the sheet sizes are different, you need to do repeat the code on each layout, one by one. Obviously, if you plot to PDF, you would get multiple PDF files instead of one PDF file with multiple pages. If you want to final result to be a single PDF file with multiple pages, you need to write extra code to "stitch" multiple PDF files into a multiple page PDF file, which is rather easy with many third party .NET PDF manipulating utililty/tool/library, such as iText (most popular open source for PDF manipulation). This is what I did with my PDF plotting app, and I guess/bet this is what AutoCAD's publishing does behind the scene.
Norman Yuan