need
Generate WORD files according to the data level. You must have a directory. The directory must have a real page number. The attachment content should be displayed in a table. The large title should be displayed as a cover.
PDF content
Big title,
Directory (with corresponding page numbers)
There is a table in the text
Key point: NPOI will not automatically generate the total number of pages when generating word files, so I use a fixed line index to calculate page numbers. Use font number 12, and one page is 44 lines. Calculate the page number according to this method. There is a better way to tell me in the comments section.
Pay attention to how to use the form
1. Note that a line will be added by default in the CreateTable() method. If you use the () method to create a new line, there will be two lines. The first behavior has only one default cell. All the correct ways are to use the (0) method
2. Note that the () method will also add a column by default. Since the first row has determined the number of columns in the table, you should use the GetCell(0) method to directly obtain the column object. 0 means the column index. The AddNewTableCell() method will add columns to the number of columns in the first row, so the correct usage is the GetCell(0) method.
Code
/// <summary> /// Generate report details file pdf /// </summary> /// <param name="model"></param> /// <param name="caseDetailsViewModels"></param> /// <param name="TargetPath">Directory Path</param> /// <param name="NewFileName">File name</param> /// <returns></returns> private static string generateWordFile(ViewModel model, List<detailsViewModel> detailsViewModels, string TargetPath, string NewFileName) { string outMergeFile = TargetPath + NewFileName; int rowIndex = 0;//Line Index //TODO: Use FileStream file stream to write data (the passed parameters are: the path of the file, the operation method of the file, and the operation of the data in the file) //Create file flow objects by using file flow, write content into file flow, and save it as Word document format using (var stream = new FileStream(outMergeFile, , )) { //Create a document object object instance XWPFDocument document = new XWPFDocument(); /** * Here I greatly reduce the redundancy of the code by setting SetParagraph (paragraph) instance creation and paragraph style formatting in public Word documents. * Avoid creating paragraph instances and setting basic paragraph styles every time one paragraph is used * (As follows, ParagraphInstanceSetting creates and styles for paragraph instances, and the index is represented as the current paragraph line, and the index starts from 0) */ //No. 12 font 44 lines per page //for (int i = 1; i <= 50; i++) //{ // (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (), true, 12, "bold", ), rowIndex); // rowIndex++; //} int iPageNum = 1;//Page Index int pageRowCount = 44;//44 lines per page //Page 1 for (int i = 1; i <= 21; i++) { (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, , true, 12, "Bold", ), rowIndex); rowIndex++; } //Text title to display a page (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, .F_ContentStr ?? , true, 20, "Bold", ), rowIndex); rowIndex++; for (int i = 1; i <= 22; i++) { (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, , true, 12, "Bold", ), rowIndex); rowIndex++; } //Empty line //(NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, , true, 12, "Stand Up", ), rowIndex); //rowIndex++; ().().Pages = iPageNum; var fontSizeTwoTitle = 16; var fontSizeTwoBody = 12; var fontSize = 12; iPageNum++; //The directory maximum row index var catalogueRowCount = iPageNum * pageRowCount; (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, "Table of contents", true, 16, "Bold", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); //1. Search purpose......................................4~4 var catalogueTest = "1. Search purpose............4~4"; //Table of Contents To display a page //TODO: This line requires two text to be displayed in this line foreach (var item in ) { if (!(item.F_ContentStr)) { StringBuilder catalogueText = new StringBuilder(item.F_ContentStr);//(" {0}.{1}", item.F_ContentStr ?? , item.F_Page ?? "1~1"); string pageNameTxt = !(item.F_Page) ? item.F_Page : "1~1"; int beginI = ().Length + ; for (int i = beginI; i < ; i++) { ("."); } (pageNameTxt); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (), false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); } } for (int i = rowIndex; i < catalogueRowCount; i++) { (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, , true, 12, "Bold", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); } #region text Starting from page 3 iPageNum = 3; int beginPageNum = 3; foreach (var item in ) { beginPageNum = ().().Pages; //title (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, ("{0}", item.F_ContentStr ?? ), false, fontSizeTwoTitle, "Songyi", , false, , "165DFF"), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); foreach (var itemThree in ) { itemThree.F_ContentStr = itemThree.F_ContentStr.Replace("\r\n", ); //content if (itemThree.F_ContentStr.Contains("</p>")) { var contentStr = itemThree.F_ContentStr.Replace("<p>", ); var contentList = ("</p>"); foreach (var itemCon in contentList) { var itemConTxt = ("\n", ).Trim(); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" {0}", itemConTxt), false, fontSizeTwoBody, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); } } else { var F_ContentStrTxt = itemThree.F_ContentStr.Replace("\n", ).Trim(); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" {0}", F_ContentStrTxt), false, fontSizeTwoBody, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); } } int pages = ().().Pages; item.F_Page = ("{0}~{1}", beginPageNum, pages); iPageNum = pages; } #endregion #region attachment if ( != null && > 0) { (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, " (I) Search result analysis list", false, fontSizeTwoTitle, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, " ", false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); int groupNum = 1; foreach (var item in ) { var KeywordTxt = !() ? : ; KeywordTxt = ("\n", ).Trim(); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" {0}", KeywordTxt), false, fontSizeTwoBody, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, " ", false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); //Note that a line will be added by default in the CreateTable() method. If you use the () method to create a new line, there will be two lines. The first behavior has only one default cell //All the correct methods are to use (0); var table = (); XWPFTableRow tableHeadRow = (0);//Add a new line (0).SetText("title"); (0).SetVerticalAlignment(); var tableHeadRowCell_CaseCode = (); tableHeadRowCell_CaseCode.SetText("Case number"); tableHeadRowCell_CaseCode.SetVerticalAlignment(); var tableHeadRowCell_IsAdd = (); tableHeadRowCell_IsAdd.SetText("Whether to join the search report"); tableHeadRowCell_IsAdd.SetVerticalAlignment(); var tableHeadRowCell_NoAddCause = (); tableHeadRowCell_NoAddCause.SetText("Reason for not joining the search report"); tableHeadRowCell_NoAddCause.SetVerticalAlignment(); foreach (var itemKey in ) { //Note that the () method will also add a column by default. Since the first row has determined the number of columns in the table, you should directly use the GetCell(0) method to obtain the column object, 0 represents the column index //AddNewTableCell() method will add columns to the number of columns in the first row, so the correct usage is the GetCell(0) method XWPFTableRow tableBodyRow = ();//Add a new line //var tableBodyRowCell_Title = (); //tableBodyRowCell_Title.SetText(itemKey.F_CaseTitle ?? ); //tableBodyRowCell_Title.SetVerticalAlignment(); (0).SetText(itemKey.F_CaseTitle ?? ); //var tableBodyRowCell_CaseCode = (); //tableBodyRowCell_CaseCode.SetText(itemKey.F_CaseCode ?? ); //tableBodyRowCell_CaseCode.SetVerticalAlignment(); (1).SetText(itemKey.F_CaseCode ?? ); //var tableBodyRowCell_IsAdd = (); //tableBodyRowCell_IsAdd.SetText(itemKey.F_IsAdd ? "Yes" : "No"); //tableBodyRowCell_IsAdd.SetVerticalAlignment(); (2).SetText(itemKey.F_IsAdd ? "yes" : "no"); (2).SetVerticalAlignment(); //var tableBodyRowCell_NoAddCause = (); //tableBodyRowCell_NoAddCause.SetText(itemKey.F_NoAddCause ?? ); //tableBodyRowCell_NoAddCause.SetVerticalAlignment(); (3).SetText(itemKey.F_NoAddCause ?? ); groupNum++; } } } #endregion #region Generate Case if (caseDetailsViewModels != null && > 0) { (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" (II) Search the full text of the case"), false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, " ", false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); foreach (var item in caseDetailsViewModels) { foreach (var itemCase in ) { //title var F_TitleTxt = itemCase.F_Title.Replace("\r\n", ); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" {0}", F_TitleTxt), false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); //content itemCase.F_Content = itemCase.F_Content.Replace("\r\n", ); if (itemCase.F_Content.Contains("</p>")) { var contentStr = itemCase.F_Content.Replace("<p>", ); var contentList = ("</p>"); foreach (var itemCon in contentList) { var itemConTxt = ("\n", ).Trim(); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" {0}", itemConTxt), false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); //if ( > iPageNum) //{ // writePageNumber(document, writer, BF_Light); //} } } else { var F_ContentTxt = itemCase.F_Content.Replace("\n", ).Trim(); (NpoiWordParagraphTextStyleHelper._.ParagraphInstanceSetting(document, (" {0}", F_ContentTxt), false, fontSize, "Songyi", ), rowIndex); setWordPages(document, ref rowIndex, pageRowCount, ref iPageNum); } } } } #endregion //Write content to the document stream to generate word (stream); } return outMergeFile; } /// <summary> /// Set the total number of pages for word /// </summary> /// <param name="document"></param> /// <param name="rowIndex">Row Index</param> /// <param name="pageRowCount">Total number of rows per page</param> /// <param name="iPageNum">Current page index</param> private static void setWordPages(XWPFDocument document, ref int rowIndex, int pageRowCount, ref int iPageNum) { rowIndex++; if (document != null) { if ((rowIndex % pageRowCount) == 0) { iPageNum++; ().().Pages = iPageNum; } } }
Call
Note: To call it twice, you don’t know which page the content in the directory is on when the first generation is generated, and the page number is collected during the first generation. A temporary file will be generated. The page number in the directory generated for the second time is the real and valid data. So it needs to be generated twice.
It’s like when you write a WORD, you don’t know how many times the content in the directory will be written. After the first and second level titles and content are written, you will generate the directory. The truth here is the same.
//word var fileNameTempPath = generateWordFile(model, caseDetailsViewModels, uploadPath, fileNameTemp); savePath = generateWordFile(model, caseDetailsViewModels, uploadPath, fileName); //Delete temporary files if ((fileNameTempPath)) { (fileNameTempPath); }
This is the end of this article about C# using Npoi to generate Word documents. For more related C# Npoi to generate Word content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!