VSD2PDF源代码,帮做你做好类似百度文库的在线文档浏览器

news/2024/11/30 10:34:00/

VSD文档转换成PDF并不是很难的事情,但在很多地方教你制作百度文库这样类似在线文档浏览器的时候,并没有告诉你怎么将VSD文档转换成SWF文档,其实VSD文档并不能直接转换成SWF文档,不管是java还是C#都没有相应的包或接口,所以必须先将VSD文档转换成PDF,然后PDF2SWF,这样就可以了。

那java怎么实现VSD文档转换PDF文档呢?java也没有包可以实现,不过可以利用Microsoft.Office.Interop.Visio.dll,采用C#做一个控制台程序。

代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using Visio = Microsoft.Office.Interop.Visio;namespace VsdToDoc
{class Program{static void Main(string[] args){String openPath = args[0];String savePath = args[1];Exec(openPath, savePath);}public static void Exec(String openPath, String savePath){Visio.ApplicationClass vsdApp = null;Visio.Document vsdDoc = null;try{vsdApp = new Visio.ApplicationClass();vsdApp.Visible = false;vsdDoc = vsdApp.Documents.Open(openPath.ToString());vsdDoc.ExportAsFixedFormat(Visio.VisFixedFormatTypes.visFixedFormatPDF,savePath.ToString(), Visio.VisDocExIntent.visDocExIntentScreen,Visio.VisPrintOutRange.visPrintAll, 1, vsdDoc.Pages.Count, false, true,true, true, true, System.Reflection.Missing.Value);Console.Write("vsd to pdf OK!!!");}catch (Exception e){Console.Write(e.Message);Console.Write("vsd to pdf error !");}finally{if (vsdDoc != null){vsdDoc.Close();vsdDoc = null;}if (vsdApp != null){vsdApp.Quit();vsdApp = null;}}}}
}


附送一个java代码,帮助你做测试


import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;import javax.imageio.ImageIO;
import javax.swing.JOptionPane;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;public class ReaderConverter {private String sourceFile;private String destinationFile;public String swfToolExePath = "";public String vsdToolExePath = "";public int openOfficePort = 0;public String openOfficeExePaht = "";private Process openOfficeServer = null;public static final Logger logger = LoggerFactory.getLogger(ReaderConverter.class);public ReaderConverter() {super();}public ReaderConverter(String swfToolExePath,String vsdToolExePath,String openOfficeExePaht,int openOfficePort) {super();this.swfToolExePath = swfToolExePath;this.vsdToolExePath = vsdToolExePath;this.openOfficeExePaht = openOfficeExePaht;this.openOfficePort = openOfficePort;}/*** 启动OpenOffice服务* * @return*/private boolean openOffice() {if (checkOpenOffice()) {return true;} else {openOfficeServer = null;String cmd = openOfficeExePaht+ " -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard";try {openOfficeServer = Runtime.getRuntime().exec(cmd);// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完logger.info("OpenOfficeServer start....");return checkOpenOffice();} catch (Exception e) {// e.printStackTrace();logger.info("OpenOfficeServer start failed!!!");return false;}}}private void stopOffice() {if(openOfficeServer != null){openOfficeServer.destroy();}logger.info("OpenOfficeServer stop....");}/*** 检查OpenOffice是否已经启动* * @return*/private boolean checkOpenOffice() {OpenOfficeConnection connection = new SocketOpenOfficeConnection(openOfficePort);try {connection.connect();} catch (ConnectException cex) {// cex.printStackTrace();connection = null;logger.info("OpenOfficeServer is stop....");} finally {// close the connectionif (connection != null) {connection.disconnect();connection = null;logger.info("OpenOfficeServer is running....");return true;}}return false;}/*** @param sourceFile*            带转换的PDF源文件地址* @param destinationFile*            转换后的SWF目标文件地址* @param exePath*            SWFTOOL的地址* @throws IOException*/private boolean pdf2swf() throws IOException {logger.info("start pdf2swf, sourceFile: " + sourceFile);Process pro = null;if (isWindowsSystem()) {// 如果是windows系统// 命令行命令String cmd = swfToolExePath + "/pdf2swf.exe" + " \"" + sourceFile+ "\" -o \"" + destinationFile + "\"  -f -T 9 ";// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);} else {// 如果是linux系统,路径不能有空格,而且一定不能用双引号,否则无法创建进程String[] cmd = new String[3];cmd[0] = swfToolExePath;cmd[1] = sourceFile;cmd[2] = destinationFile;// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);}try {// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完loadStream(pro.getInputStream());loadStream(pro.getErrorStream());// System.out.print(loadStream(pro.getInputStream()));// System.err.print(loadStream(pro.getErrorStream()));pro.waitFor();} catch (InterruptedException e) {e.printStackTrace();}return (new File(destinationFile)).exists();}private boolean png2swf() throws IOException {logger.info("start png2swf, sourceFile: " + sourceFile);Process pro = null;if (isWindowsSystem()) {// 如果是windows系统// 命令行命令String cmd = swfToolExePath + "/png2swf.exe" + " \"" + sourceFile+ "\" -o \"" + destinationFile + "\"  -T 9 ";// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);} else {// 如果是linux系统,路径不能有空格,而且一定不能用双引号,否则无法创建进程String[] cmd = new String[3];cmd[0] = swfToolExePath;cmd[1] = sourceFile;cmd[2] = destinationFile;// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);}try {// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完loadStream(pro.getInputStream());loadStream(pro.getErrorStream());System.out.print(loadStream(pro.getInputStream()));System.err.print(loadStream(pro.getErrorStream()));pro.waitFor();} catch (InterruptedException e) {e.printStackTrace();}return (new File(destinationFile)).exists();}private boolean gif2swf() throws IOException {logger.info("start gif2swf, sourceFile: " + sourceFile);Process pro = null;if (isWindowsSystem()) {// 如果是windows系统// 命令行命令String cmd = swfToolExePath + "/gif2swf.exe" + " \"" + sourceFile+ "\" -o \"" + destinationFile + "\" ";// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);} else {// 如果是linux系统,路径不能有空格,而且一定不能用双引号,否则无法创建进程String[] cmd = new String[3];cmd[0] = swfToolExePath;cmd[1] = sourceFile;cmd[2] = destinationFile;// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);}try {// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完loadStream(pro.getInputStream());loadStream(pro.getErrorStream());System.out.print(loadStream(pro.getInputStream()));System.err.print(loadStream(pro.getErrorStream()));pro.waitFor();} catch (InterruptedException e) {e.printStackTrace();}return (new File(destinationFile)).exists();}private boolean jpg2swf() throws IOException {logger.info("start jpg2swf, sourceFile: " + sourceFile);Process pro = null;if (isWindowsSystem()) {// 如果是windows系统// 命令行命令String cmd = swfToolExePath + "/jpeg2swf.exe" + " \"" + sourceFile+ "\" -o \"" + destinationFile + "\"   -T 9 ";// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);} else {// 如果是linux系统,路径不能有空格,而且一定不能用双引号,否则无法创建进程String[] cmd = new String[3];cmd[0] = swfToolExePath;cmd[1] = sourceFile;cmd[2] = destinationFile;// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);}try {// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完loadStream(pro.getInputStream());loadStream(pro.getErrorStream());System.out.print(loadStream(pro.getInputStream()));System.err.print(loadStream(pro.getErrorStream()));pro.waitFor();} catch (InterruptedException e) {e.printStackTrace();}return (new File(destinationFile)).exists();}private boolean bmp2swf() throws IOException {logger.info("start bmp2swf, sourceFile: " + sourceFile);String JPGFile = "";// 文件路径String filePath = destinationFile.substring(0,destinationFile.lastIndexOf("/"));// 文件名,不带后缀String fileName = destinationFile.substring((filePath.length() + 1),destinationFile.lastIndexOf("."));JPGFile = filePath + "/" + fileName + ".jpg";//转换BMP2JPGBMPToJPG(sourceFile, JPGFile);sourceFile = JPGFile;Process pro = null;if (isWindowsSystem()) {// 如果是windows系统// 命令行命令String cmd = swfToolExePath + "/jpeg2swf.exe" + " \"" + sourceFile+ "\" -o \"" + destinationFile + "\"   -T 9 ";// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);} else {// 如果是linux系统,路径不能有空格,而且一定不能用双引号,否则无法创建进程String[] cmd = new String[3];cmd[0] = swfToolExePath;cmd[1] = sourceFile;cmd[2] = destinationFile;// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);}try {// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完loadStream(pro.getInputStream());loadStream(pro.getErrorStream());System.out.print(loadStream(pro.getInputStream()));System.err.print(loadStream(pro.getErrorStream()));pro.waitFor();} catch (InterruptedException e) {e.printStackTrace();}// 删除临时的jpg文件,沉睡1秒钟,保证临时文件不被占用boolean deleteOK =	(new File(sourceFile)).delete();logger.info("delete temp file: " + sourceFile + " result is "+deleteOK);return (new File(destinationFile)).exists();}private boolean vsd2pdf() throws IOException{logger.info("start vsd2pdf, sourceFile: " + sourceFile);String PDFFile = "";// 文件路径String filePath = destinationFile.substring(0,destinationFile.lastIndexOf("/"));// 文件名,不带后缀String fileName = destinationFile.substring((filePath.length() + 1),destinationFile.lastIndexOf("."));PDFFile = filePath + "/" + fileName + ".pdf";Process pro = null;if (isWindowsSystem()) {// 如果是windows系统// 命令行命令String cmd = vsdToolExePath + "/VsdToDoc.exe" + " \"" + sourceFile+ "\" \"" + PDFFile + "\"";// Runtime执行后返回创建的进程对象pro = Runtime.getRuntime().exec(cmd);} try {// 调用waitFor方法,是为了阻塞当前进程,直到cmd执行完loadStream(pro.getInputStream());loadStream(pro.getErrorStream());System.out.print(loadStream(pro.getInputStream()));System.err.print(loadStream(pro.getErrorStream()));pro.waitFor();} catch (InterruptedException e) {e.printStackTrace();}sourceFile = PDFFile;return (new File(sourceFile)).exists();}private boolean doc2pdf() {logger.info("start doc2pdf, sourceFile: " + sourceFile);String PDFFile = "";// 文件路径String filePath = destinationFile.substring(0,destinationFile.lastIndexOf("/"));// 文件名,不带后缀String fileName = destinationFile.substring((filePath.length() + 1),destinationFile.lastIndexOf("."));PDFFile = filePath + "/" + fileName + ".pdf";// 处理txt、xml文件格式的特殊代码,将txt的后缀名改为odt. ,处理WPS的文件则 将 文件后缀名改为 对应Office的文件的后缀名,Boolean isNeedCreateTempFile = (isTXTFile(sourceFile) || isWPSFile(sourceFile));if (isNeedCreateTempFile) {try {String tempFilePostfix = "";if (sourceFile.toLowerCase().indexOf(".txt") > 1) {tempFilePostfix = "odt";}if (sourceFile.toLowerCase().indexOf(".xml") > 1) {tempFilePostfix = "odt";}if (sourceFile.toLowerCase().indexOf(".wps") > 1) {tempFilePostfix = "docx";}if (sourceFile.toLowerCase().indexOf(".dps") > 1) {tempFilePostfix = "pptx";}if (sourceFile.toLowerCase().indexOf(".et") > 1) {tempFilePostfix = "xlsx";}copyFile(sourceFile, filePath + "/" + fileName + "."+ tempFilePostfix);sourceFile = filePath + "/" + fileName + "." + tempFilePostfix;} catch (Exception e) {e.printStackTrace();}}openOffice();OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);try {connection.connect();DocumentConverter converter = new OpenOfficeDocumentConverter(connection);converter.convert(new File(sourceFile), new File(PDFFile));} catch (ConnectException cex) {cex.printStackTrace();} finally {// close the connectionif (connection != null) {connection.disconnect();connection = null;}}stopOffice();// 删除临时的odt文件,沉睡1秒钟,保证临时文件不被占用if (isNeedCreateTempFile) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}boolean deleteOK =	(new File(sourceFile)).delete();logger.info("delete temp file: " + sourceFile + " result is "+deleteOK);}sourceFile = PDFFile;return (new File(sourceFile)).exists();}/* * 转换主方法 *//*** @param sourceFile*            office file or pdf file full path read as* @param destinationFile*            swf file full path save as* @return*/public boolean conver(String sourceFile, String destinationFile) {this.sourceFile = sourceFile;this.destinationFile = destinationFile;try {// 如果已经是PDF则不需要转换if (isPDFFile(sourceFile)) {logger.info("sourceFile: " + sourceFile+ " ,is PDF file not need doc2pdf.");pdf2swf();} else if (isPNGFile(sourceFile)) {logger.info("sourceFile: " + sourceFile+ " ,is png file not need doc2pdf.");png2swf();} else if (isGIFFile(sourceFile)) {logger.info("sourceFile: " + sourceFile+ " ,is gif file not need doc2pdf.");gif2swf();} else if (isJPGFile(sourceFile)) {logger.info("sourceFile: " + sourceFile+ " ,is jpg file not need doc2pdf.");jpg2swf();} else if (isBMPFile(sourceFile)) {logger.info("sourceFile: " + sourceFile+ " ,is bmp file not need doc2pdf.");bmp2swf();} else if (isVSDFile(sourceFile)) {logger.info("sourceFile: " + sourceFile+ " ,is visio file need vsd2pdf.");if (vsd2pdf()) {pdf2swf();}// 删除临时的PDF文件(new File(this.sourceFile)).delete();}else {if (doc2pdf()) {pdf2swf();}// 删除临时的PDF文件(new File(this.sourceFile)).delete();}} catch (Exception e) {e.printStackTrace();return false;}if ((new File(destinationFile)).exists()) {logger.info("conver successful, destinationFile: "+ destinationFile);return true;} else {logger.info("conver failed, destinationFile: " + destinationFile);return false;}}public String loadStream(InputStream in) throws IOException {int ptr = 0;in = new BufferedInputStream(in);StringBuffer buffer = new StringBuffer();while ((ptr = in.read()) != -1) {buffer.append((char) ptr);}return buffer.toString();}/*** 判断是否是windows操作系统* * @return*/private boolean isWindowsSystem() {String p = System.getProperty("os.name");return p.toLowerCase().indexOf("windows") >= 0 ? true : false;}/*** 根据后缀名判断文件是否为PDF文件* * @return*/private boolean isPDFFile(String filePath) {return filePath.toLowerCase().indexOf(".pdf") > 1 ? true : false;}/*** 根据后缀名判断文件是否为WPS系列的文件* * @return*/private boolean isWPSFile(String filePath) {return (filePath.toLowerCase().indexOf(".wps") > 1|| filePath.toLowerCase().indexOf(".dps") > 1 || filePath.toLowerCase().indexOf(".et") > 1) ? true : false;}/*** 根据后缀名判断文件是否为TXT文件* * @return*/private boolean isTXTFile(String filePath) {return (filePath.toLowerCase().indexOf(".txt") > 1 || filePath.toLowerCase().indexOf(".xml") > 1) ? true : false;}/*** 根据后缀名判断文件是否为PNG文件* * @return*/private boolean isPNGFile(String filePath) {return filePath.toLowerCase().indexOf(".png") > 1 ? true : false;}/*** 根据后缀名判断文件是否为GIF文件* * @return*/private boolean isGIFFile(String filePath) {return filePath.toLowerCase().indexOf(".gif") > 1 ? true : false;}/*** 根据后缀名判断文件是否为JPG文件* * @return*/private boolean isJPGFile(String filePath) {return (filePath.toLowerCase().indexOf(".jpg") > 1 || filePath.toLowerCase().indexOf(".jpeg") > 1) ? true : false;}/*** 根据后缀名判断文件是否为BMP文件* * @return*/private boolean isBMPFile(String filePath) {return filePath.toLowerCase().indexOf(".bmp") > 1 ? true : false;}/*** 根据后缀名判断文件是否为Visio文件* * @return*/private boolean isVSDFile(String filePath) {return filePath.toLowerCase().indexOf(".vsd") > 1 ? true : false;}/*** 复制单个文件* * @param oldPath*            String 原文件路径 如:c:/fqf.txt* @param newPath*            String 复制后路径 如:f:/fqf.txt* @throws Exception*/public static void copyFile(String oldPath, String newPath)throws Exception {InputStream inStream = null;FileOutputStream fs = null;try {int bytesum = 0;int byteread = 0;File oldfile = new File(oldPath);if (oldfile.exists()) { // 文件存在时inStream = new FileInputStream(oldPath); // 读入原文件fs = new FileOutputStream(newPath);byte[] buffer = new byte[1444];while ((byteread = inStream.read(buffer)) != -1) {bytesum += byteread; // 字节数 文件大小// System.out.println(bytesum);fs.write(buffer, 0, byteread);}}} catch (Exception e) {System.out.println("复制单个文件操作出错");e.printStackTrace();throw e;} finally {if (inStream != null) {inStream.close();}if (fs != null) {fs.close();}}}/*** BMP文件转换成JPG文件* @param src* @param des*/private void BMPToJPG(String src, String des) {File file = new File(src);if (file.exists() == false) {return;}try {Image img = ImageIO.read(file);BufferedImage tag = new BufferedImage(img.getWidth(null),img.getHeight(null), BufferedImage.TYPE_INT_RGB);tag.getGraphics().drawImage(img.getScaledInstance(img.getWidth(null),img.getHeight(null), Image.SCALE_SMOOTH), 0, 0,null);FileOutputStream out = new FileOutputStream(des);JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(tag);out.close();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 测试main方法* * @param args*/public static void main(String[] args) {ReaderConverter reader = new ReaderConverter("C:/SWFTools","C:/VsdToPdf","C:/openoffice.org 3/program/soffice", 8100);reader.conver("c:/1.pptx", "c:/1.swf");reader.conver("c:/2.docx", "c:/2.swf");reader.conver("c:/3.pdf", "c:/3.swf");reader.conver("c:/4.odt", "c:/4.swf");reader.conver("c:/5.bmp", "c:/5.swf"); reader.conver("c:/6.jpg", "c:/6.swf");   reader.conver("c:/7.png", "c:/7.swf");reader.conver("c:/8.gif", "c:/8.swf");reader.conver("c:/9.vsd", "c:/9.swf");reader.conver("c:/10.txt", "c:/10.swf");reader.conver("c:/11.wps", "c:/11.swf");reader.conver("c:/12.dps", "c:/12.swf");reader.conver("c:/13.et", "c:/13.swf");reader.conver("c:/14.xml", "c:/14.swf");}}



public class BMPReader {private void BMPToJPG(String src, String des) {File file = new File(src);if (file.exists() == false) {JOptionPane.showMessageDialog(null, "文件不存在!", "提示",JOptionPane.INFORMATION_MESSAGE);return;}try {Image img = ImageIO.read(file);BufferedImage tag = new BufferedImage(img.getWidth(null),img.getHeight(null), BufferedImage.TYPE_INT_RGB);tag.getGraphics().drawImage(img.getScaledInstance(img.getWidth(null),img.getHeight(null), Image.SCALE_SMOOTH), 0, 0,null);FileOutputStream out = new FileOutputStream(des);JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(tag);out.close();JOptionPane.showMessageDialog(null, "转换完成!", "提示",JOptionPane.INFORMATION_MESSAGE);} catch (IOException e) {e.printStackTrace();} catch (ImageFormatException e) {e.printStackTrace();}}}



http://www.ppmy.cn/news/112698.html

相关文章

【Stateflow】Chart初始化时访问data store memory警告

应用Stateflow的时候,涉及到Data Store Memory作为全局变量的时候的一个错误,记录下来。 1. 问题描述 变量xxx是用Data Store Memory在外层定义的全局变量,Stateflow状态图在初始默认转移中的转移动作为对其赋值: 编译运行后&a…

TGCA数据的标准化以及差异分析--转载

转载果子学生信 https://mp.weixin.qq.com/s/Ph1O6V5RkxkyrKpVmB5ODA 前面我们从GDC下载了TCGA肿瘤数据库的数据,也能够把GDC下载的多个TCGA文件批量读入R 今天我们讲一下TCGA数据的标准化,以及差异分析,得到了标准化后的数据,我们就可以按照以前的帖子,做一系列操作

ie visio 打开_Visio viewer 不能从IE打开vsd文件(转) | 学步园

问题描述:在安装了visio viewer 2003 的XP系统中双击.vsd文件,跳出IE,选允许Active运行,显示一个红叉叉,不能打开。 原因:微软的KB973525引起 解决方案: 1. 保留Visio Viewer 2003卸载系统补丁KB973525 2…

java读取vsd文件_java下载文件指定目录下的文件

方法一: RequestMapping(download) def download(HttpServletRequest request, HttpServletResponse response) { TtxSession session getSession(request) String fileNameOrderData--20190225.csv String pathName"C:\\export\\OrderData--20190225.csv&quo…

visio的vsd文件转eps图流程

一.我先吐个槽 作图不难但是太特么麻烦啦!!! 谁让我作图? 二.方法选择 visio的vsd文件转成eps网上有多种方法,我很懒的,随便选个能用就行 vsd→pdf→eps ##三具体操作 ###0.前期准备 需要将vds文件导出为pdf文件,那么自然需要pdf打印机,所以!,你需要安装一个Adobe Acrobat…

骨科创伤感染治疗中应用VSD的临床效果研究

摘要:目的 探讨骨科创伤感染治疗中应用负压封闭引流技术(VSD)的临床效果。方法 选择2012年7月~2019年7月于我院就诊的70例骨科创伤感染患者作为研究对象,随机分为观察组35例和对照组35例。对照组给予常规换药治疗,观察组给予VSD治疗。对比两组患者一般指…

ie visio 打开_Visio viewer 不能从IE打开vsd文件

问题描述:在安装了visio viewer 2003 的XP系统中双击.vsd文件,跳出IE,选允许Active运行,显示一个红叉叉,不能打开。 原因:微软的KB973525引起 解决方案: 1. 保留Visio Viewer 2003卸载系统补丁KB973525 2…

什么是服务器工程文件格式,Visio找不到数据库建模功能怎么办 VSD文件是什么格式...

Visio如何制作数据库模型图?Visio找不到数据库模型图功能怎么办?VSD文件是什么?使用什么软件可以打开和编辑VSD文件?Visio是微软办公套件的一个组成部分,是流程图、数据图的制作工具,Visio也有数据库模型图。VSD文件是Visio制作的一种文件格式,Visio可以打开并编辑VSD文…