【问题标题】:(DOORS/DXL) Export to pdf or print with a given template(DOORS/DXL) 导出为 pdf 或使用给定模板打印
【发布时间】:2012-11-07 08:45:33
【问题描述】:

我们有兴趣从正式模块中导出/打印一个视图。由于我们希望它可以是一个官方文档,我们希望添加我们的公司模板,该模板具有自己的首页、具有给定文本字体、大小和颜色的页眉和页脚,以及插入的图像(公司符号、客户的)。

据我所知,DOORS 允许我们打印添加页眉和页脚但没有图像。另一方面,可以添加模板导出到 Word,但我不能直接将其导出为 pdf 格式或打印机。

对我们来说重要的是,可以在没有 Word 或任何其他编辑器管理的情况下直接由门制作公司文档,以便 DOORS 文档可以直接发布给客户而无需外部更改。

是否可以通过 DXL 脚本实现?或者还有其他选择吗?

我想许多用户必须使用他们公司的公司图片打印(或制作 pdf 文件),我认为这非常有用。

【问题讨论】:

    标签: pdf pdf-generation report ibm-doors


    【解决方案1】:

    是否可以通过 DXL 脚本实现?

    恕我直言。我已经编写了一个 DXL 脚本来将 DOORS 模块导出到可以编译成 PDF 的 LaTeX 文件。您将在此答案的末尾找到它。随意调整它以适应您的需求。在运行它之前,您需要下载“Smart Folder Browser”的源代码并将其存储在我的脚本旁边作为“smartFolderBrowser.inc”。 Die extension inc 表示这是一个包含文件,而不是一个独立的 DXl 程序。

    当然,每个想要使用这种方法的用户都需要一个已安装的 TeX 发行版,例如 MiKTeX。 DXL 脚本可以在导出后使用 DXL 内置函数void system(string command) 启动 PDF 构建。

    使用您的自定义 DXL LaTeX 导出脚本,您将必须完全控制生成的 PDF 的布局。但请注意 TeX 应用的布局规则。配置(强制)TeX 以呈现使用 M$ Word 创建的文档可能是一项非常具有挑战性的任务。

    // DOORS LaTeX Export
    /**
    Copyright (c) 2012-2013 Kai K.
    
    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:
    
    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */
    pragma encoding, "UTF-8"
    
    
    #include "smartFolderBrowser.inc"
    
    DBE dbeOutputFolder = null;
    DBE dbeOptions = null;
    bool withTitles = true
    Buffer tempBuf = create;
    
    void escapeSpecialLaTeXCharacters(Buffer& str)
    {
       Buffer temp = create;
    
       int i = 0;
       for(i = 0; i < length(str); ++i) 
       {
          char c = str[i]; 
          if( '\\' == c ) 
          {
             temp += "\\textbackslash{}";
          }
          else if( '{' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '}' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '_' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '^' == c )
          {
             temp += "\\textasciicircum{}";
          }
          else if( '#' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '&' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '$' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '%' == c )
          {
             temp += "\\"
             temp += c
          }
          else if( '~' == c )
          {
             temp += "\\textasciitilde{}";
          }
          else
          {
             temp += c;
          }
       }
    
       str = tempStringOf(temp);
       delete temp;
    }
    
    string makeLabel(Buffer& str)
    {
       setempty(tempBuf);
    
       int i = 0;
       for(i = 0; i < length(str); ++i) 
       {
          char c = str[i]; 
          if( ' ' != c && '-' != c && '\n' != c && '\\' != c && '_' != c && '#' != c) 
          {
             tempBuf += c;
          }
       }
       return stringOf(tempBuf);
    }
    
    string makeCaption(Buffer& str)
    {
       setempty(tempBuf);
    
       int i = 0;
       for(i = 0; i < length(str); ++i) 
       {
          char c = str[i]; 
          if( '\n' != c && '\\' != c) 
          {
             tempBuf += c;
          }
       }
       escapeSpecialLaTeXCharacters(tempBuf);
       return stringOf(tempBuf);
    }
    
    void rtf2latex(Buffer& buf)
    {
       Buffer txt = create;
       Buffer temp = create;
       RichTextParagraph rp = null;
       bool envopened = false;
       for rp in tempStringOf(buf) do {
          if(rp.indentLevel > 0)
          {
             real hspace = realOf(rp.indentLevel)/20.0;
             temp += "{\\hangindent" hspace "pt\\hangafter0"
          }
          if(rp.isBullet)
          {
             temp += "\\textbullet ";
          }      
          RichText rt = null      
          for rt in rp do {
             txt = rt.text;         
                escapeSpecialLaTeXCharacters(txt);
    
             if (rt.italic)
             {
                temp += "\\textit{";
                temp += txt;
                temp += "}";
             }
             else if (rt.bold)
             {
                temp += "\\textbf{";
                temp += txt;
                temp += "}";
             }
             else if (rt.strikethru)
             {
                temp += "\\sout{";
                temp += txt;
                temp += "}";
             }
             else if (rt.subscript)
             {
                temp += "\\textsubscript{";
                temp += txt;
                temp += "}";
             }
             else if (rt.superscript)
             {
                temp += "\\textsuperscript{";
                temp += txt;
                temp += "}";
             }
             else if (rt.underline)
             {
                temp += "\\underline{";
                temp += txt;
                temp += "}";
             }         
             else
             {
                temp += txt;
             }
             if (rt.newline && !rt.last)
             {
                temp += "\\par\n";
             }
             else if(rt.last)
             {
                temp += "\n";
             }
          }
          if(rp.indentLevel > 0)
          {
             temp += "}"
          }
       }
       buf = tempStringOf(temp);
       delete temp;
       delete txt;  
    }
    
    void getObjectText(Object obj, Buffer& buf)
    {  
       if(!null(obj))
       {
          buf = richTextFragment(richText(obj."Object Text"));
          rtf2latex(buf);
       }
       else
       {
          buf = "null";
          print("ERROR: obj null!: "dxlHere() "\n");
       }   
    }
    
    int nextCell(Stream& oss, int curCol, int numCols )
    {
       if( curCol == numCols )
       {
          oss << "\\\\\n\\hline\n"
       }
       else
       {
          oss << "\t&\t"
       }
    
       return( curCol % numCols + 1 )
    }
    
    void writePreamble(Stream& oss)
    {
       oss << "\\documentclass[a4paper]{book}\n";
       oss << "%---- packages ----\n";
       oss << "\\usepackage{ulem}\n";
       oss << "\\usepackage{color}\n";
       oss << "\\usepackage{graphicx}\n";
       oss << "\\usepackage{supertabular}\n";
       oss << "\\usepackage{hyperref}\n";
       oss << "\\usepackage{makeidx}\n";
       oss << "\\usepackage{xltxtra}\n";
       oss << "\\makeindex\n";
       oss << "%\n---- settings ----\n";
       oss << "\\setcounter{secnumdepth}{6}\n";
       oss << "\\setlength{\\parindent}{0}\n";
       oss << "\\setlength{\\parskip}{2x}\n";
       oss << "%\n---- customizations ----\n";
       oss << "\\makeatletter\n";
       oss << "\\def\\maxwidth{%\n";
       oss << "\\ifdim\\Gin@nat@width>\\linewidth\n";
       oss << "\\linewidth\n";
       oss << "\\else\n";
       oss << "\\Gin@nat@width\n";
       oss << "\\fi\n";
       oss << "}\n";
       oss << "\\makeatother\n";
       oss << "\n%---- document ----\n";
       oss << "\\begin{document}\n";
       oss << "\\tableofcontents\n";
       oss << "\\listoffigures\n";
       oss << "\\listoftables\n";
    }
    
    void writeTableHeader(Stream& oss, Object tableobj, int& numCols )
    {
       //print("Enter: writeTableHeader\n");
       numCols = 0
       int numRows = 0;
       int tableWidth = 0;
    
       Object cellobj = null;
       Object rowobj = null;
       // first count the columns and rows
       for rowobj in table( tableobj ) do {
          if( !isDeleted( rowobj ) )
          {
             if(numCols == 0)
             {
                for cellobj in rowobj do {
                   if( !isDeleted( cellobj ))
                   {
                      tableWidth += getCellWidth(cellobj);
                      numCols++;              
                   }
                }
             }
             numRows++;
          }
       }
    
       // extract the header row
       int colCount = numCols;
       int col = 0;   
       Object headrow[colCount];
       for rowobj in table( tableobj ) do {
          if( !isDeleted( rowobj ) )
          {
             if(col == 0)
             {
                for cellobj in rowobj do {
                   if( !isDeleted( cellobj ))
                   {
                      headrow[col] = cellobj;
                      col++;
                   }
                }
             }
             else
             {            
                break;
             }
          }
       }
    
       // export the table head
       oss << "\\begin{centering}\n";
    
       Buffer buf = create;
       oss << "\\tablefirsthead{";   
       for(col=0; col<colCount; ++col) {
          getObjectText(headrow[col], buf);
          oss << tempStringOf(buf);
          if(col+1<colCount)
             oss << "&";
       }
       oss << "\\\\}\n";
    
       oss << "\\tablehead{";
       for(col=0; col<colCount; ++col) {   
          getObjectText(headrow[col], buf);
          oss << tempStringOf(buf);
          if(col+1<colCount)
             oss << "&";         
       }
       oss << "\\\\}\n";
       oss << "\\tabletail{\\hline}\n";   
    
       oss << "\\begin{supertabular}{|";
       for(col=0; col<colCount; ++col) {
          cellobj = headrow[col];
          int w = getCellWidth(cellobj);
          real rw = w;
          real tw = tableWidth;
          w = intOf(rw/tw*100.0);
          rw = realOf(w)/100.0;
          oss << "p{" rw "\\textwidth}|";
       }  
       oss << "}\n\\hline\n"
    
       delete buf;
    
       //print("Leave: writeTableHeader\n");
    }
    
    void writeTableFooter(Stream& oss, Buffer& objtext)
    {
       oss << "\\\\\n\\hline\n"
       oss << "\\end{supertabular}\n\\label{tab:";
       oss << makeLabel( objtext );
       oss << "}\n\\bottomcaption{"
       oss << makeCaption( objtext );
       oss << "}\n\\end{centering}\n"
    }
    
    void writeobjheading(Stream& oss, Buffer &objNum, Buffer &text, int level )
    {
       if(1 == level)
       {
          oss << "\\chapter{";
       }
       else if(2 == level)
       {
          oss << "\\section{";        
       }
       else if(3 == level)
       {
          oss << "\\subsection{";        
       }
       else if(4 == level)
       {
          oss << "\\subsubsection{";        
       }
       else if(5 == level)
       {
          oss << "\\paragraph{";        
       }
       else
       {
          oss << "\\subparagraph{";        
       }
    
       oss << tempStringOf(text);
       oss << "}\n\\label{sec:";
       oss << makeLabel(text);
       oss << makeLabel(objNum);
       oss << "}\n";
    }
    
    void writeFigureHeadAndExport(Stream& oss, Object img, string outputDir)
    {
       Module mod = module(img);   
       string n = mod."Prefix"img."Absolute Number"".png";
       string s = exportPicture(img, outputDir "\\" n, formatPNG);   
       oss << "\\begin{figure}[ht]\n";
       oss << "\\centering\n";
       oss << "\\includegraphics[width=\\textwidth]{"n"}\n";
    }
    
    void writeFigureFooter(Stream& oss, Buffer& objtext)
    {
       oss << "\\label{fig:";
       oss << makeLabel( objtext );
       oss << "}\n\\caption{"
       oss << makeCaption( objtext );
       oss << "}\n\\end{figure}\n";
    }
    
    void writeRequirement(Stream& oss, Module& doorsModule, Object obj, Buffer& puid, Buffer& objtext)
    {
       oss << "\\textbf{";
       oss << tempStringOf( puid );
       oss << "}\\\\\n" //"PUID style"
       oss << "\\label{req:";
       oss << makeLabel(puid)
       oss << "}\n";
       oss << "\\index{";
       oss << tempStringOf( puid );
       oss << "}\n";
       oss << "\\color{blue}\n"
       oss << tempStringOf( objtext )
       oss << "\n"//"requirement style"
    
       oss << "\\begin{tabbing}\n"
       Column col = null;
       Buffer var_name = create;
       int c=0;   
       for col in doorsModule do {      
          var_name = title( col )
          escapeSpecialLaTeXCharacters(var_name);
    
          if( ! main( col ) && search( regexp "(P|p)(U|u)(I|i)(D|d)", var_name, 0 ) == false )
          {         
             oss << "\\textbf{";
             oss << var_name;
             if(c == 0)
                oss <<  "}: \\hspace{2.0cm} \\= "
             else
                oss <<  "}: \\> "
    
             var_name = text( col, obj );
             escapeSpecialLaTeXCharacters(var_name);
             oss << var_name;
             oss << "\\\\\n";// "attribute valueBuf" )
             c++;
          }               
       }
       oss << "\\end{tabbing}\n"
       oss << "\\color{black}\n"
       delete var_name;
    }
    
    void timeString( int timeInSeconds, Buffer &t )
    {
       t = ""
    
       int hours, minutes, seconds
    
       hours    =   timeInSeconds / 3600
       minutes  = ( timeInSeconds - hours * 3600 ) / 60
       seconds  = ( timeInSeconds - hours * 3600 - minutes * 60 )
    
       if( hours < 10 ) t = "0"
       t += ( hours "")
       t += ":"
       if( minutes < 10 ) t += "0"
       t += ( minutes "")
       t += ":"
       if( seconds < 10 ) t += "0"
       t += ( seconds "")
    }
    
    void doExport(DB db)
    {
       int startTime = intOf( today )
    
       int progressLimit = 0;
       Object obj = null;
       for obj in current Module do {
          progressLimit++;
       }
    
       progressStart(db, "Exporting Module as LaTeX", "Object 0/"progressLimit"", progressLimit);
       string outputDir = get(dbeOutputFolder);
       string outputFileName = name(current Module);
       string outputFileExt = ".tex";
       string outputFilePath = outputDir "\\" outputFileName outputFileExt;
    
       Stream mainFile = write(outputFilePath);
       Stream oss = mainFile;
    
       writePreamble(oss);
    
       int progress = 1;
       int curCol = 1;
       int numCols = 0;
       bool lastObjWasFigure = false;
       bool lastObjWasTable = false;
    
       Buffer objheading = create;
       Buffer objtext = create;
       Buffer objNum = create;
       Buffer puid = create;
    
       int lev = 0
       int puidLevel = 0
       Regexp excel = regexp "objclass Excel.Sheet"
       Module doorsModule = current Module;
       int subfileCount = 1;
       for obj in current Module do {
          if(progressCancelled())
          {
             if( confirm(db, "Do you really want to abort the export?") )
             {
                break;
             }
          }
    
          progressMessage("Object "progress"/"progressLimit"");
    
          getObjectText(obj, objtext)
    
          // ------------------- Handle Tables ------------------------------------
          if( cell( obj ))
          {
             if( !lastObjWasTable )
             {
                writeTableHeader(oss, obj, numCols);            
                curCol           = 1;
                lastObjWasTable  = true;
             }
             else
             {
                curCol = nextCell(oss, curCol, numCols );
             }
             oss << tempStringOf( objtext ); // "Standard"
             progressStep(progress);
             progress++;
             continue
          }
    
          // ------------------- After Table write Table Title -----------------
          if( lastObjWasTable )
          {
             writeTableFooter(oss, objtext);
          }
          // ------------------- After Figure write Figure Title ---------------
          if( lastObjWasFigure )
          {
             writeFigureFooter(oss, objtext)
          }
    
          objNum  = number( obj )
          objheading = obj."Object Heading"
          escapeSpecialLaTeXCharacters(objheading)
    
          // ------------------- Handle End of Requirement ------------------------
          lev = level( obj )
          if( lev <= puidLevel )
          {
             //oss << "End Requirement\n\n"
             puidLevel = 0
          }
    
          if( withTitles && ( lastObjWasTable || lastObjWasFigure ))
          {
             lastObjWasTable  = false
             lastObjWasFigure = false
             continue
          }
    
          // ------------------- Handle objheading with hierarchy --------------------
          if( length( objheading ) > 0 )
          {
             writeobjheading(oss, objNum, objheading, lev )
          }
    
          if( length( objtext ) > 0 )
          {
             // remember, if Title has to be written after this object
             if( containsOle( obj."Object Text"))
             {
                if( excel objtext ) {
                   lastObjWasTable = true
                }
                else
                {
                   lastObjWasFigure = true;
                   writeFigureHeadAndExport(oss, obj, outputDir);
                }
             }
             // ------------------- Handle Requirements objects Text -----------
             puid = obj."IE PUID"
             escapeSpecialLaTeXCharacters(puid)
             if( length( puid ) > 0 )
             {
                puidLevel = lev
                writeRequirement(oss, doorsModule, obj, puid, objtext);
             }
             // ------------------- No PUID means normal text Object -----------
             else
             {
                oss << tempStringOf( objtext );
                oss << "\n";// "Standard"
             }
          }
    
    
          progressStep(progress);
          progress++;      
       }
    
       oss << "\\printindex\n"
       oss << "\\end{document}\n";
    
       close(oss);
       progressStop();
    
       // ---------------------- show the result ----------------------------------
       int endTime = intOf( today ) - startTime
    
       Buffer totalTime = create;
       timeString( endTime, totalTime );
    
       infoBox( "Export successfully finished after " totalTime "\nThe result is located in\n" outputFilePath);
    
       delete objheading;
       delete objtext;
       delete objNum;
       delete puid;
       delete tempBuf;
    }
    
    DB db = create("LaTeX Export");
    dbeOutputFolder = smartFolderBrowser(db, "Output Folder:", false);
    
    ok(db, doExport);
    show(db);
    

    【讨论】:

    • 您好。谢谢您的回答。我将开始了解有关 MikTeX 的一些信息。它对我来说是新的,所以我要检查一下,看看我是否可以使用它。因为我不是 dxl 程序员,所以我不确定。
    • 我已经下载了 MikTeX。据我了解,我需要您的 DXL 脚本来导出 LaTeX 文件,我正在使用 dxl 标签修改所有问题,但我还没有找到。关于准备自定义 DXL 以获得带有图像的个性化封面和页眉/页脚页面,您能给我更多详细信息吗?我是一个新手,我对在 dxl 编程不太了解。谢谢!!
    • @Jose:你当然没找到。我从未发布过代码。我会看看我是否可以在某处上传代码并在此处分享链接。但这可能需要一段时间……在此之前,我建议您开始阅读 DOORS 提供的 DXL 参考资料。
    • 谢谢!但是,当我尝试运行它时会显示错误: italic bold -E- DXL: &lt;Line:27&gt; could not open include file (utils/smartFolderBrowser.inc) (No such file or directory)
    • 嘿@JoseManuelMorenoRamos,经过 8 年和 5 次投票,您可以接受我的回答 ;-)
    【解决方案2】:

    您使用的是哪个版本的 DOORS?

    在 DOORS 9.3+ 中,IBM 将 RPE 的功能合并到 DOORS 中,这允许您有更多的导出选项,包括导出为 PDF。但是,直到 DOORS 9.4.0.1(当前版本),您才可以在 IBM Rational Publishing Engine (RPE) 中构建自己的模板并直接在 DOORS 中使用该模板。

    因此,答案是您需要一份 IBM 的 RPE Full 许可证,以便您可以创建您正在寻找的模板,然后在您的公司中使用 DOORS 的任何人都可以使用该模板导出 DOORS 文档,而无需额外的许可证。您还需要使用 DOORS 9.4.0.1。

    我还看到一些公司将其页眉和页脚导出到 Word,然后使用 Adob​​e Acrobat 在其封面页中添加徽标等。然而,这意味着只有拥有 Acrobat 完整许可证的人才能正确生成文档。

    RPE 绝对是您的最佳选择。

    【讨论】:

    • 据我所知,我们有 Doors 9.3...所以我想我无法解决这个问题...我会尝试确认谢谢!!
    • 我确信它可以用 DXL 以某种方式完成。但是在编写脚本时,您可以升级到 9.4.0.1。这不值得付出努力。
    • 我已经确认我们已经安装了 9.3 版本。我不确定我们是否会更新到 9.4。正如您所说,我们的方式是导出到 Word,然后使用 Adob​​e Acrobat。我们有他们所有的执照。但是我想避免这些中间步骤,以避免有人可以修改报告。所以我认为最好的方法是直接用我们自己的封面和页面格式打印。无论如何,谢谢你的帮助。我们应该继续使用 Word 作为打印 Doors 报告的中间步骤,尽管它可以轻松修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多