• C# 导出word文档及批量导出word文档(4)


          接下来是批量导出word文档和批量打印word文件,批量导出word文档和批量打印word文件的思路差不多,只是批量打印不用打包压缩文件,而是把所有文件合成一个word,然后通过js来调用word,提交打印机,把word文档的内容都打印出来。
         批量导出word文档需要用到ICSharpCode.SharpZipLib.dll 插件,思路是,先单独导出所勾选的数据的单个文档,保存到生成的临时目录下,再把同一个的人相关文档合并一个word文档,并删除已经合并的那个文档(不是合并后生成的文档),以姓名和编号命名生成后的文档,最后将临时目录下的所有文件打包压缩下载,并删除临时目录和临时目录下的所有文件(都是生成在服务器上,所以若文件太大,可能会慢)。批量导出是用form来提交所传的参数,并下载。(因为懒,不解释代码了)
          首先新建一个空文档,插入书签,书签名为“p”(随便定义的),命名文件名为“test.doc”,保存在项目目录下。       
          相关js代码为:     
      1  /***************************************
      2  * @methodname→批量导出word文档
      3  * @createtime 2015-05-11
      4  ***************************************/
      5 function AllExportWord(objid, tfile) {
      6     var ckvalue = "", ntid = "", code = "", name = "";
      7     var chkbox = $("input[type=checkbox][name=chk]:checked");
      8     for (var i = 0; i < chkbox.length; i++) {
      9         ckvalue = ckvalue + chkbox[i].value + ",";  //主键值
     10         ntid = ntid + $(chkbox[i]).attr("data-ntid") + ","; //学生主键
     11         code = code + $(chkbox[i]).attr("data-code") + ","; //胸卡号
     12         name = name + $(chkbox[i]).attr("data-name") + ","; //姓名
     13     }
     14     if (ckvalue != "") {
     15         ntid = ntid.substring(0, ntid.length - 1);
     16         code = code.substring(0, code.length - 1);
     17         name = name.substring(0, name.length - 1);
     18         $.ajax({
     19             type: "POST",
     20             url: "/NewStudent/BatchExportWord",
     21             dataType: "json",
     22             data: { tempFile: tfile, ntid: ntid },
     23             async: false,
     24             success: function (data) {
     25                 if (data.isOK) {
     26                     var count = ntid.split(',').length;
     27                     if (count == data.ls.length && count > 0) {
     28                         DownLoadWord(objid, tfile, ntid, code, name, true);
     29                     }
     30                     else {
     31                         if (confirm("选择导出的数据中包含没有学习记录的数据,是否确认导出或打印?")) {
     32                             DownLoadWord(objid, tfile, ntid, code, name, true);
     33                         }
     34                     }
     35                 }
     36                 else {
     37                     alert(data.msg);
     38                 }
     39             }
     40         });
     41     }
     42     else {
     43         alert("请选择数据!");
     44     }
     45 }
     46 /***************************************
     47  * @methodname→批量导出word文档
     48  * @createtime 2015-05-11
     49  ***************************************/
     50 function BatchExportWord(objid, tfile) {   
     51     var ckvalue = "", ntid = "", code = "", name = "";
     52     var chkbox = $("input[type=checkbox][name=chk]:checked");
     53     for (var i = 0; i < chkbox.length; i++) {
     54         ckvalue = ckvalue + chkbox[i].value + ",";  //主键值
     55         ntid = $(chkbox[i]).attr("data-ntid"); //学生主键
     56         code = $(chkbox[i]).attr("data-code"); //胸卡号
     57         name = $(chkbox[i]).attr("data-name"); //姓名
     58     }
     59     if (ckvalue != "") {
     60         ckvalue = ckvalue.substring(0, ckvalue.length - 1); //去掉最后一个逗号
     61         $.ajax({
     62             type: "POST",
     63             url: "/NewStudent/BatchExportWord",
     64             dataType: "json",
     65             data: { tempFile: tfile },
     66             async: false,
     67             success: function (data) {
     68                 if (data.isOK) {
     69                     DownLoadWord(objid, tfile, ntid, code, name, false)
     70                 }
     71                 else {
     72                     alert(data.msg);
     73                 }
     74 
     75             }
     76         });
     77     }
     78     else {
     79         alert("请选择数据!");
     80     }
     81 }
     82 /*************************************************
     83  * @methodname→只能通过流的方式批量导出word文档
     84    在页尾添加form,通过提交form表单才能下载
     85  * @createtime 2015-05-12
     86  *************************************************/
     87 function DownLoadWord(idName, tfile, ntid, code, name, isAll) {   
     88     $("body").find("form.#form1").remove();
     89     var form = "<form id='form1'></form>";
     90     var input = "<input />";
     91     var input1 = "", input2 = "", input3 = "", input4 = "", input5 = "", input6 = "";
     92     input1 = $(input); input1.attr("type", "hidden"); input1.attr("name", "tempFile"); input1.attr("value", tfile);
     93     input2 = $(input); input2.attr("type", "hidden"); input2.attr("name", "ntid"); input2.attr("value", ntid);
     94     input3 = $(input); input3.attr("type", "hidden"); input3.attr("name", "code"); input3.attr("value", code);
     95     input4 = $(input); input4.attr("type", "hidden"); input4.attr("name", "name"); input4.attr("value", name);
     96     input5 = $(input); input5.attr("type", "hidden"); input5.attr("name", "isAll"); input5.attr("value", isAll);
     97     input6 = $(input); input6.attr("type", "hidden"); input6.attr("name", "idName"); input6.attr("value", idName);
     98     $("body").append(form); //将表单放置在web中
     99     //添加表单属性
    100     $("#form1").attr("style", "display:none");
    101     $("#form1").attr("target", "");
    102     $("#form1").attr("method", "post");   
    103     $("#form1").attr("action", "/NewStudent/DownLoadWord");  
    104   
    105     //添加input到表单里
    106     $("#form1").append(input1)
    107     $("#form1").append(input1);
    108     $("#form1").append(input2);
    109     $("#form1").append(input3);
    110     $("#form1").append(input4);
    111     $("#form1").append(input5);
    112     $("#form1").append(input6);
    113     $("#form1").submit();
    114 }
    js

         相关后台代码如下: 

      1 #region 压缩文件及文件夹
      2     /// <summary>
      3     /// 压缩文件及文件夹
      4     /// </summary>
      5     public class CompressFileZip
      6     {
      7         private ZipOutputStream zos = null;
      8         private string strBaseDir = "";
      9 
     10         #region 临时文件夹名称
     11         /// <summary>
     12         /// 临时文件夹名称
     13         /// </summary>
     14         /// <param name="name">学生名称</param>
     15         /// <param name="value">学生卡号</param>
     16         /// <returns></returns>
     17         public string FolderName(string name, string value)
     18         {
     19             string tempName = "";
     20             if (!string.IsNullOrEmpty(name))
     21             {
     22                 tempName = name;
     23                 if (!string.IsNullOrEmpty(value))
     24                     tempName += "_" + value;
     25                 tempName += "_" + DateTime.Now.ToString("yyyyMMddHHmm");
     26             }
     27             else
     28             {
     29                 tempName = DateTime.Now.ToString("yyyyMMddHHmmss"); //临时文件夹名称
     30             }
     31             return tempName;
     32         }
     33         #endregion
     34 
     35         #region 创建临时文件夹
     36         /// <summary>
     37         /// 创建临时文件夹
     38         /// </summary>
     39         /// <param name="name">学生名称</param>
     40         /// <param name="value">学生卡号</param>
     41         /// <returns></returns>
     42         public string CreateTempFolder(string name, string value = null)
     43         {
     44             //遍历服务器指定文件夹下的所有文件
     45             string path = "UploadFile";
     46             string serverPath = WordFilePath.GetFilePath(path);
     47             string tempName = "";
     48             if (!string.IsNullOrEmpty(value))
     49                 tempName = FolderName(name, value);
     50             else
     51                 tempName = name;
     52             string tempFolder = Path.Combine(serverPath, tempName);
     53             Directory.CreateDirectory(tempFolder); //创建临时文件夹
     54             //DirectoryInfo folder = new DirectoryInfo(serverPath);
     55             return tempFolder + "\";
     56         }
     57         #endregion
     58 
     59         #region 添加文件到压缩文件中
     60         /// <summary>
     61         /// 添加文件到压缩文件中
     62         /// </summary>
     63         /// <param name="PathStr">路径</param>
     64         public void addZipEntry(string PathStr)
     65         {
     66             DirectoryInfo di = new DirectoryInfo(PathStr);
     67             foreach (DirectoryInfo item in di.GetDirectories())
     68             {
     69                 addZipEntry(item.FullName);
     70             }
     71             foreach (FileInfo item in di.GetFiles())
     72             {
     73                 FileStream fs = System.IO.File.OpenRead(item.FullName);
     74                 byte[] buffer = new byte[fs.Length];
     75                 fs.Read(buffer, 0, buffer.Length);
     76                 string strEntryName = item.FullName.Replace(strBaseDir, "");
     77                 ZipEntry entry = new ZipEntry(strEntryName);
     78                 zos.PutNextEntry(entry);
     79                 zos.Write(buffer, 0, buffer.Length);
     80                 fs.Close();
     81             }
     82         }
     83         #endregion
     84 
     85         #region 输出下载压缩包
     86         /// <summary>
     87         /// 输出下载压缩包
     88         /// </summary>
     89         /// <param name="response">页面响应</param>
     90         /// <param name="strPath">文件所在的路径</param>
     91         /// <param name="strFileName">压缩文件名</param>
     92         /// <param name="strExt">压缩文件的扩展名</param>
     93         public void dlZipDir(HttpResponseBase response, string strPath, string strFileName, string strExt = null)
     94         {
     95             if (string.IsNullOrEmpty(strExt))
     96                 strExt = ".zip"; //默认压缩文件扩展名
     97             MemoryStream ms = null;
     98             response.ContentType = "application/octet-stream";
     99             strFileName = HttpUtility.UrlEncode(strFileName).Replace('+', ' ');
    100             response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName + strExt);
    101             ms = new MemoryStream();
    102             zos = new ZipOutputStream(ms);
    103             strBaseDir = strPath + "\";
    104             addZipEntry(strBaseDir);
    105             zos.Finish();
    106             zos.Close();
    107             response.Clear();
    108             response.BinaryWrite(ms.ToArray());
    109             //删除临时目录下的所有文件
    110             DeleteTempFiles(strPath);
    111             //删除空目录
    112             Directory.Delete(strPath);
    113             response.End();
    114         }
    115         #endregion
    116 
    117         #region 保存文件到临时文件夹中
    118         /// <summary>
    119         /// 保存文件到临时文件夹中
    120         /// </summary>
    121         /// <param name="content">将流内容写入字节组</param>
    122         /// <param name="SaveName">保存的文件名</param>
    123         /// /// <param name="dirPath">保存路径</param>
    124         /// <param name="fileExtend">保存的文件扩展名</param>
    125         /// <returns></returns>
    126         public void SaveFile(byte[] content, string SaveName, string dirPath, string fileExtend = null)
    127         {
    128 
    129             if (string.IsNullOrEmpty(fileExtend))
    130                 fileExtend = ".doc"; //文件扩展名默认是word文档
    131             try
    132             {
    133                 DateTime dt = DateTime.Now;
    134                 //设置文件夹路径
    135                 //directory = CreateTempFolder(strName, strCode);
    136                 //文件保存完整路径
    137                 string path = dirPath + SaveName + fileExtend;
    138                 //验证文件夹是否存在   不存在则创建
    139                 if (!Directory.Exists(dirPath))
    140                 {
    141                     Directory.CreateDirectory(dirPath);
    142                 }
    143                 //以创建文件的方式写入内容
    144                 FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write);
    145                 BinaryWriter w = new BinaryWriter(fs);
    146                 w.Write(content);
    147                 w.Close();
    148                 fs.Close();
    149             }
    150             catch (Exception ex)
    151             {
    152                 throw new System.IO.FileNotFoundException("目录:" + dirPath + "没有找到!");
    153             }
    154         }
    155         #endregion
    156 
    157         #region 删除临时目录下的所有文件
    158         /// <summary>
    159         /// 删除临时目录下的所有文件
    160         /// </summary>
    161         /// <param name="tempPath">临时目录路径</param>
    162         private void DeleteTempFiles(string tempPath)
    163         {
    164             DirectoryInfo directory = new DirectoryInfo(tempPath);
    165             try
    166             {
    167                 foreach (FileInfo file in directory.GetFiles())
    168                 {
    169                     if (file.Attributes.ToString().IndexOf("ReadOnly") != -1)
    170                     {
    171                         file.Attributes = FileAttributes.Normal;
    172                     }
    173                     System.IO.File.Delete(file.FullName);
    174                 }
    175             }
    176             catch (Exception)
    177             {
    178                 throw;
    179             }
    180         }
    181         #endregion
    182 
    183         #region 获取指定文件夹下的所有文件
    184         /// <summary>
    185         /// 获取指定文件夹下的所有文件
    186         /// </summary>
    187         /// <param name="Folder">文件夹名称</param>
    188         /// <param name="strName">文件夹下所包含指定文件名的文件</param>
    189         /// <returns></returns>
    190         public List<string> GetFileList(string Folder, string strName = null)
    191         {
    192             List<string> lsFile = new List<string>();
    193             if (!string.IsNullOrEmpty(Folder))
    194             {
    195                 Folder = WordFilePath.GetFilePath("UploadFile", Folder + "\");
    196                 DirectoryInfo di = new DirectoryInfo(Folder);
    197                 foreach (FileInfo item in di.GetFiles())
    198                 {
    199                     if (!string.IsNullOrEmpty(strName))
    200                     {
    201                         if (item.FullName.Contains(strName))
    202                             lsFile.Add(item.FullName);
    203                     }
    204                     else
    205                         lsFile.Add(item.FullName);
    206                 }
    207             }
    208             return lsFile;
    209         } 
    210         #endregion
    211 
    212     }
    213     #endregion 
    214 
    215     #region 插入文档
    216     public class InsertFile
    217     {
    218         #region 在书签位置插入另一个文档的内容
    219         /// <summary>
    220         /// 使用DocumentBuilder对象插入一些文档对象,如插入书签,插入文本框,插入复选框
    221         /// 插入一个段落,插入空白页,追加或另一个word文件的内容等。
    222         /// </summary>
    223         /// <param name="doc">载入模板</param>
    224         /// <param name="tempFile"></param>
    225         /// <param name="mark">载入模版名称</param>
    226         /// <param name="lsFile"></param>
    227         public static void InsertDoc(Document doc, string mark, List<string> lsFile, string SaveName = null)
    228         {
    229             string savePath = "";
    230             var builder = new DocumentBuilder(doc);
    231             if (!string.IsNullOrEmpty(SaveName))
    232                 SaveName = SaveName.Substring(0, SaveName.LastIndexOf("_"));
    233             Document doc1;
    234             for (int i = 0; i < lsFile.Count; i++)
    235             {
    236                 if (i == 0)
    237                     savePath = lsFile[i].Substring(0, lsFile[i].LastIndexOf('\') + 1);
    238                 doc1 = new Document(lsFile[i]);//新文档
    239                 var bookmark = doc.Range.Bookmarks[mark];
    240                 //清空书签的文本
    241                 //bookmark.Text = "";
    242                 //定位到指定位置进行插入操作
    243                 builder.MoveToBookmark(mark, false, false);
    244                 InsertDocument(bookmark.BookmarkStart.ParentNode, doc1);
    245                 //doc.FirstSection.PageSetup.SectionStart = SectionStart.NewPage;
    246                 //doc1.AppendDocument(doc, ImportFormatMode.KeepSourceFormatting);
    247 
    248                 System.IO.File.Delete(lsFile[i]); //删除已经插入的文件                
    249             }
    250             if (!string.IsNullOrEmpty(SaveName))
    251                 doc.Save(savePath + SaveName + ".doc");
    252         }
    253         #endregion
    254 
    255         #region 插入文档
    256         /// <summary>
    257         /// 插入文档
    258         /// </summary>
    259         /// <param name="insertAfterNode">节点在目标文件中的内容后插入。这个节点应该是一个块级节点(段落或表格)。</param>
    260         /// <param name="srcDoc">插入文档</param>
    261         private static void InsertDocument(Node insertAfterNode, Document srcDoc)
    262         {
    263             // 确保插入点是一个段落或表格。
    264             if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) &
    265               (!insertAfterNode.NodeType.Equals(NodeType.Table)))
    266                 throw new ArgumentException("插入的目的节点应该是一个段落或表格。");
    267 
    268             // 插入到目标段落
    269             CompositeNode dstStory = insertAfterNode.ParentNode;
    270             NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting);
    271 
    272             //在源文件中循环
    273             foreach (Section srcSection in srcDoc.Sections)
    274             {
    275                 foreach (Node srcNode in srcSection.Body)
    276                 {
    277                     // 跳过空节点
    278                     if (srcNode.NodeType.Equals(NodeType.Paragraph))
    279                     {
    280                         Paragraph para = (Paragraph)srcNode;
    281                         if (para.IsEndOfSection && !para.HasChildNodes)
    282                             continue;
    283                     }
    284                     // 插入到目标文档
    285                     Node newNode = importer.ImportNode(srcNode, true);
    286                     // 参考节点后插入新节点
    287                     dstStory.InsertAfter(newNode, insertAfterNode);
    288                     insertAfterNode = newNode;
    289                 }
    290             }
    291         }
    292         #endregion
    293     }
    294     #endregion 
    Code

        页面调用的方式如下:

    1 <input id="Export" type="button" class="s_btn" value="批量导出" onclick="AllExportWord(this.id, '接收进修生手册导出模板')" />
    2  <input id="Print" type="button" class="s_btn" value="批量打印" onclick="AllExportWord(this.id, '接收进修生手册导出模板')" />
    3  <input type="checkbox" name="chk" id="chk" value='@item.CardNo' data-ntid="@item.NTID" data-code="@item.CardNo" data-name="@item.NTName" /></td>
    Html

        这里的this.id是传当前请求的按钮的id,因为调用的方法都一样,所以同时传id,加以区分页面的请求,以实现不同的功能。
    controller调用的方法: 

      1        #region 批量下载文件前的验证
      2       /// <summary>
      3         /// 批量下载文件前的验证
      4      /// </summary>
      5         /// <param name="tempFile">模板</param>
      6         /// <param name="ntid">学生主键</param>
      7         /// <returns></returns>
      8         public JsonResult BatchExportWord(string tempFile, string ntid = null)
      9         {
     10             bool isOK = false;
     11             string msg = "";
     12             string strpath = "Content/templates";
     13             List<string> ls = new List<string>();
     14             if (!string.IsNullOrEmpty(tempFile))
     15             {
     16                 if (Path.GetExtension(tempFile) != ".doc")
     17                     tempFile = tempFile + ".doc";
     18                 isOK = WordFilePath.ExistFile(strpath, tempFile);
     19                 if (!isOK)
     20                     msg = "导出的模板不存在!";
     21                 else
     22                 {
     23                     if (!string.IsNullOrEmpty(ntid))
     24                     {
     25                         string[] strNTID = ntid.Split(',');
     26                         for (int i = 0; i < strNTID.Length; i++)
     27                         {
     28                             NameValueCollection nvc = new NameValueCollection();
     29                             nvc.Add(GetPropertyName<Model.MajorCycle>(m => m.NTID), strNTID[i]);
     30                             IList<Model.MajorCycle> lsMCycle = new BLL.MajorCycle().GetModelList<Model.MajorCycle>(nvc);
     31                             if (lsMCycle.Count > 0)
     32                                 ls.Add(string.Join(",", lsMCycle.Select(m => m.ID)));
     33                         }
     34                     }
     35                 }
     36             }
     37             else
     38             {
     39                 msg = "导出的模板为空!";
     40             }
     41             return Json(new { isOK = isOK, msg = msg, ls = ls });
     42         }
     43         #endregion
     44 
     45         #region 下载压缩包
     46         /// <summary>
     47         /// 下载压缩包
     48         /// </summary>
     49         /// <param name="tempFile">模板</param>
     50         /// <param name="ntid">学生主键</param>
     51         /// <param name="code">学生编号</param>
     52         /// <param name="name">学生名称</param>
     53         /// <param name="isAll">是否全部导出</param>
     54         /// <param name="idName">请求按钮id名称</param>
     55         /// <returns></returns>
     56         public FileContentResult DownLoadWord(string tempFile, string ntid, string code, string name, string isAll, string idName)
     57         {
     58             CompressFileZip fileZip = new CompressFileZip();
     59             string saveName = "", dirPath = "", GzipFileName = "", mid = "", stype = "", sequence = "";
     60             Document doc = new Document();
     61             var docStream = new MemoryStream();
     62             if (!string.IsNullOrEmpty(ntid))
     63             {
     64                 string[] strNTID = ntid.Split(',');
     65                 string[] strCode = code.Split(',');
     66                 string[] strName = name.Split(',');
     67                 for (int i = 0; i < strNTID.Length; i++)
     68                 {
     69                     if (i == 0) //第一次时创建临时文件夹
     70                     {
     71                         if (!string.IsNullOrEmpty(isAll) && isAll == "true")
     72                             GzipFileName = fileZip.FolderName(tempFile.Substring(0, tempFile.IndexOf("") + 1), "");
     73                         else
     74                             GzipFileName = fileZip.FolderName(strName[i], strCode[i]);
     75                         dirPath = fileZip.CreateTempFolder(GzipFileName);
     76                     }
     77                     NameValueCollection nvc = new NameValueCollection();
     78                     nvc.Add(GetPropertyName<Model.MajorCycle>(m => m.NTID), strNTID[i]);
     79                     IList<Model.MajorCycle> lsMCycle = new BLL.MajorCycle().GetModelList<Model.MajorCycle>(nvc);
     80                     if (lsMCycle.Count > 0) //如果不以这方式,则没有学习记录的数据导出来会是一个空的压缩包,什么文件也没有
     81                     {
     82                         mid = string.Join(",", lsMCycle.Select(m => m.MajorID)); // 轮转科室id
     83                         stype = lsMCycle[0].StudentType.ToString().Trim(); // 学生类型
     84                         sequence = string.Join(",", lsMCycle.Select(m => m.Sequence)); // 轮转次数
     85                     }
     86                     string[] midArr = mid.Split(',');
     87                     string[] sequenceArr = sequence.Split(',');
     88                     mid = ""; sequence = "";
     89                     for (int j = 0; j < midArr.Length; j++)
     90                     {
     91                         saveName = strName[i] + "_" + strCode[i] + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
     92                         WordHelper wordhelper = new WordHelper(tempFile);
     93                         getWordInfo(wordhelper, tempFile, strNTID[i], stype, midArr[j], sequenceArr[j]);
     94                         fileZip.SaveFile(wordhelper.ExportDoc().ToArray(), saveName, dirPath);
     95                     }
     96                     if (!string.IsNullOrEmpty(isAll) && isAll == "true" && idName == "Export")
     97                     {
     98                         doc = new Document(WordFilePath.GetFilePath("Content/templates", "test.doc"));
     99                         InsertFile.InsertDoc(doc, "p", fileZip.GetFileList(GzipFileName, strName[i]), saveName);
    100                     }
    101 
    102                 }
    103                 if (idName == "Export")
    104                     fileZip.dlZipDir(Response, WordFilePath.GetFilePath("UploadFile", GzipFileName), GzipFileName); //压缩下载
    105             }
    106 
    107             if (idName == "Print") //打印
    108             {
    109                 doc = new Document(WordFilePath.GetFilePath("Content/templates", "test.doc"));
    110                 InsertFile.InsertDoc(doc, "p", fileZip.GetFileList(GzipFileName));                
    111                 doc.Save(docStream, SaveOptions.CreateSaveOptions(SaveFormat.Doc));
    112                 Directory.Delete(WordFilePath.GetFilePath("UploadFile", GzipFileName));
    113             }
    114             return base.File(docStream.ToArray(), "application/msword", GzipFileName);
    115         }
    116         #endregion 
    View Code

      导出的效果如下图:             图片              生成的临时文件夹:          

    图片

          同一人的首先生成单个文件

    图片

            将两个文件合并成一个文件,以姓名和编号命名,同时删除合并前生成的那两个文件:

    图片

          循环生成 下一个人的单个文档

    图片

         合并文件,以姓名和编号命名,同时删除合并前的文件:

    图片
         打包压缩合并后的这两个文件,并下载:
    图片   
     

           打印的效果如下图:         将所有人的有关文档都生成单个文件 

    图片

           最后合并成一个文件,并输出:

    图片
  • 相关阅读:
    【洛谷P3901】数列找不同
    【洛谷P2966】Cow Toll Paths
    【CH6901】骑士放置
    【洛谷P2215】上升序列
    【洛谷P1637】三元上升子序列
    【POJ2226】Muddy Fields
    【UVA1194】Machine Schedule
    【CH6803】导弹防御塔
    【CH6802】车的放置
    hdu 3572(构图+最大流)
  • 原文地址:https://www.cnblogs.com/jingshuisihan/p/4604321.html
Copyright © 2020-2023  润新知