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