www.gusucode.com > rptgen 工具箱matlab源码程序 > rptgen/+mlreportgen/Word.m
classdef Word < handle % Word % % Wraps a Word application. % % Copyright 2014 The MathWorks, Inc. methods (Static) function hWord = getApp(action) persistent cachedWordComObject hWord = []; if (nargin > 0 && strcmpi(action, '-clear')) cachedWordComObject = []; return; end if ~isempty(cachedWordComObject) try cachedWordComObject.Version; hWord = cachedWordComObject; return catch ME %#ok<NASGU> cachedWordComObject = []; end end if isempty(cachedWordComObject) try %#ok<TRYNC> hWord = actxserver('word.application'); end cachedWordComObject = hWord; end end function closeApp() hWord = mlreportgen.Word.getApp(); if (hWord.Documents.Count > 0) % Do not close app if there are open documents return end %we don't want to quit if we are background printing or saving while get(hWord,'BackgroundPrintingStatus') || ... get(hWord,'BackgroundSavingStatus') pause(.25); end try %#ok % call hWord.Quit(saveChanges) invoke(hWord,'Quit',false); % The quit command appears to complete in a separate thread. We need to % give it time to finish before proceeding pause(1); mlreportgen.Word.clearCachedWordApp(); end end function hSelection = getSelection() hWord = mlreportgen.Word.getApp(); hSelection = hWord.Selection; end function hdoc = findDocument(filename) hWord = mlreportgen.Word.getApp(); hdoc = []; hDocs = hWord.documents; openCount = hDocs.count; for i=1:openCount; thisDoc = hDocs.Item(i); if strcmpi(thisDoc.FullName,filename) hdoc = thisDoc; return; end end end function hDoc = findDoc(fileName) hWord = mlreportgen.Word.getApp(); hDocs = hWord.documents; hDoc = []; openCount = hDocs.count; for i = 1:openCount thisDoc = hDocs.Item(i); if strcmpi(thisDoc.FullName,fileName) hDoc = thisDoc; return end end end function activateDoc(hDoc) try % Note: some versions of Word return an argument from Activate and % others don't. We don't need the information either way. invoke(hDoc, 'Activate'); catch ME error(message('rptgen:rptgenrptgen:cannotActivate',... fileName,... ME.message)); end end function hDoc = openDoc(fileName) hWord = mlreportgen.Word.getApp(); hDoc = mlreportgen.Word.findDoc(fileName); if isempty(hDoc) hDocs = hWord.documents; try % call to hDocs.open(file, confirmDocConversion) hDoc = invoke(hDocs,'open',fileName,false); % There is a slight delay (by Word) when opening a document. If we % don't allow it to complete, subsequent commands will fail quietly pause(1); mlreportgen.Word.activateDoc(hDoc); hWord.Visible = 1; hWord.Activate; hWord.WindowState = 0; catch ME error(message('rptgen:rptgenrptgen:cannotOpen',... fileName,... ME.message)); end else % Bring window to the front hDoc.Windows.Item(1).Activate; hWord.Activate; end end function hDoc = openStyleSheet(filename) hDoc = mlreportgen.Word.openDoc(filename); hWord = mlreportgen.Word.getApp(); % See http://msdn.microsoft.com/en-us/library/office/bb214033%28v=office.12%29.aspx % for list of Word dialog enumerations. % 1948 = wdDialogStyleManagement hWord.Dialogs.Item(1948).Display; end function closeDoc(hDoc, fileName) try invoke(hDoc,'Close',false); catch ME error(message('rptgen:rptgenrptgen:cannotClose',... fileName,... ME.message)); end end %-------------------------------------------------------------------------- function makeDocVisible(hDoc, fileName) hWord = mlreportgen.Word.getApp(); if (hWord.Visible == 0) %Make Word window visible and flag as "saved" so word does not query %when closing try hWord.WindowState = false; %Word should not be maximized hWord.Visible = true; hDoc.Saved = true; % Shouldn't really be here, will move this call out later catch ME mlreportgen.Word.closeApp(); error(message('rptgen:rptgenrptgen:cannotMakeVisible',... fileName,... ME.message)); end end end function printDoc(hDoc, fileName) try invoke(hDoc,'PrintOut'); catch ME error(message('rptgen:rptgenrptgen:cannotPrintDoc',... fileName,... ME.message)); end end function saveAsDoc(hDoc, fileName) try if length(fileName) > 3 && strcmpi(fileName(end-2:end),'doc') docFileName = fileName; else [fPath,fName] = fileparts(fileName); docFileName = fullfile(fPath,[fName,'.doc']); end [outputPath, outputFileName, outputFileExt] = fileparts(docFileName); tempName = fullfile(outputPath,[outputFileName '-temp' outputFileExt]); %Ideally, I'd use wdFormatDocument here. I can't figure out how to %get the constant, though, so I'm hardcoding. % http://msdn.microsoft.com/en-us/library/bb238158.aspx % Search for "WdSaveFormat Enumeration" on msdn docFormat = 0; if ismethod(hDoc,'SaveAs') hDoc.SaveAs(tempName,docFormat); else % Word 2010, api changed to SaveAs2 % We are not checking against version number because it is a string. The ISMETHOD is much % more reliable. % http://msdn.microsoft.com/en-us/library/ff836084.aspx hDoc.SaveAs2(tempName,docFormat); end hDoc.Close(); movefile(tempName,docFileName,'f'); catch ME error(message('rptgen:rptgenrptgen:cannotSaveAsDoc', ... fileName,... ME.message)); end end function saveDoc(hDoc, varargin) % saveDoc(hDoc) saves and closes hDoc. % saveDoc(hDoc, tf) saves and closes hDOc if tf==true; otherwise, % it simply saves the hDoc. if isempty(varargin) isToClose = true; else isToClose = varargin{1}; end try hDoc.Save(); if isToClose hDoc.Close(); end catch ME error(message('rptgen:rptgenrptgen:cannotSaveDoc')); end end function convertDOCXToPDF(hDoc, fileName, showPDF) if ispc try [path, name, ~] = fileparts(fileName); pdfFileName = fullfile(path, [name '.pdf']); wdFormatPDF = 17; invoke(hDoc, 'SaveAs', pdfFileName, wdFormatPDF); hDoc.Close(); if showPDF winopen(pdfFileName); end catch ME error(message('rptgen:rptgenrptgen:cannotConvertToPDF',... fileName,... ME.message)); end end end function hWord = clearCachedApp() hWord = mlreportgen.Word.getApp('-clear'); end function version = getVersion() hWord = mlreportgen.Word.getApp(); version = hWord.Version; end function updateFields(hDoc, fileName) try %Re-layout pictures before updating page references imgFound = mlreportgen.Word.updateFieldsCollection(hDoc.Fields); % Update all headers and footers for sectionIndex = 1:hDoc.Sections.Count curSection = hDoc.Sections.Item(sectionIndex); for headerIndex = 1:curSection.Headers.Count imgFound = mlreportgen.Word.updateFieldsCollection(curSection.Headers.Item(headerIndex).Range.Fields) | imgFound; end for footerIndex = 1:curSection.Footers.Count imgFound = mlreportgen.Word.updateFieldsCollection(curSection.Footers.Item(footerIndex).Range.Fields) | imgFound; end end if imgFound %Images were found. Update the page layout. hDoc.Repaginate; end docFields = hDoc.Fields; fieldCount = docFields.Count; for i = 1:fieldCount %Update non-image, non-include fields. Mostly, this is page %numbers. docItem = docFields.Item(i); if ~(strcmp(docItem.Type,'wdFieldIncludePicture') || ... strcmp(docItem.Type,'wdFieldIncludeText')) docItem.Update; end end catch ME error(message('rptgen:rptgenrptgen:cannotUpdateFields',... fileName,... ME.message)); end end function imageFound = updateFieldsCollection(fieldsColl) imageFound = false; fieldCount = fieldsColl.Count; i = 1; while (i <= fieldCount) curItem = fieldsColl.Item(i); fieldType = curItem.Type; if strcmp(fieldType,'wdFieldIncludePicture') curItem.Update; imageFound = true; elseif strcmp(fieldType,'wdFieldIncludeText') curItem.Update; imageFound = true; %If the included text contains fields, the total field count %will change fieldCount = fieldsColl.Count; end i = i+1; end end function updateDocxFields(hDoc,fileName) try mlreportgen.Word.updateFields(hDoc, fileName); hDoc.Repaginate; tocs = hDoc.TablesOfContents; for i = 1:tocs.Count tocs.Item(i).Update(); end return; catch ME %#ok<NASGU> end try mlreportgen.Word.updateFields(hDoc, fileName); hDoc.Repaginate; docFields = hDoc.Fields; % Update the following fields before updating the TOC of % tables. This is because the table TOC is generated from % the table title style, which contains a numbering building % block that uses the STYLEREF and SEQ fields. for i=1:docFields.Count docItem = docFields.Item(i); fieldType = docItem.Type; if strcmp(fieldType,'wdFieldStyleRef') || strcmp(fieldType,'wdFieldSequence') docItem.Update; end end % Update the table TOC. The following updates every TOC. A slight % optimization might be to find and upate only the table TOC> for i=1:docFields.Count docItem = docFields.Item(i); fieldType = docItem.Type; if strcmp(fieldType,'wdFieldTOC') docItem.Update; end end catch ME error(message('rptgen:rptgenrptgen:cannotUpdateFields',... fileName,... ME.message)); end end end end